use std::thread::JoinHandle;
use zhur_common::flume::{Receiver, Sender};
use zhur_common::log::*;
use super::ExecutorMsg;
/// This struct contains the actual code engine used to run user-provided apps.
pub struct InnerExecutor {
/// Inner executor's numeral ID. Inherited from the outer `Executor` struct.
id: usize,
msg_rx: Receiver<ExecutorMsg>,
done_tx: Sender<()>,
}
impl InnerExecutor {
pub fn new(id: usize, msg_rx: Receiver<ExecutorMsg>, done_tx: Sender<()>) -> Self {
Self {id, msg_rx, done_tx}
}
/// Handles incoming `ExecutorMsg`s and decides whether or not the executor's loop should continue to run by returning a `bool`.
fn handle(&mut self) -> bool {
let msg = match self.msg_rx.recv() {
Ok(msg) => msg,
Err(_) => {
let text = format!("Inner WASM executor #1 could not receive a message from its outer executor thread!");
error!("{}", &text);
panic!("{}", &text);
}
};
match msg {
ExecutorMsg::LoadCode(_v) => {
trace!("Inner WASM executor #{} was requested to reload its code.", self.id);
trace!("Not actually doing anything, WASM not implemented yet.");
},
ExecutorMsg::Invoke(_env) => {
trace!("Inner WASM executor #{} received an invocation.", self.id);
trace!("Not actually doing anything, WASM not implemented yet.");
match _env.1.send(b"PLACEHOLDER".to_vec()) {
Ok(_) => (),
Err(_) => {
let text = format!("Inner WASM executor #{} could not respond to the invocation it got!", self.id);
error!("{}", &text);
panic!("{}", &text);
}
}
match self.done_tx.send(()) {
Ok(_) => (),
Err(_) => {
let text = format!("Inner WASM executor #{} could not report a successful execution!", self.id);
error!("{}", &text);
panic!("{}", &text);
}
}
},
ExecutorMsg::Shutdown => {
trace!("Inner WASM executor #{} was told to shut down.", self.id);
return false // quit thread loop
}
}
true
}
/// Runs the executor in a background thread and returns a join handle to said thread.
pub fn run_as_thread(self) -> JoinHandle<()> {
let id = self.id;
let builder = std::thread::Builder::new();
match builder
.name(format!("inner_executor_{}", self.id))
.spawn(move || {
let mut exec = self;
loop {
if !exec.handle() {
break;
}
}
}) {
Ok(h) => h,
Err(_) => {
let text = format!("Inner WASM executor #{} could not be launched as a thread!", id);
error!("{}", &text);
panic!("{}", &text);
}
}
}
}\