// Spawns a running wasmtime instance with the given context and status
// channel. Due to the Instance type not being Send safe, all of the logic
// needs to be done within the spawned task
Spawns a running wasmtime instance with the given context and status
channel. Due to the Instance type not being Send safe, all of the logic
needs to be done within the spawned task
Spawns a running wasmtime instance with the given context and status channel . Due to the Instance type not being Send safe all of the logic needs to be done within the spawned task
async fn spawn_wasm3(
        &self,
        _output_write: std::fs::File,
    ) -> anyhow::Result<JoinHandle<anyhow::Result<()>>> {
        // Clone the module data Arc so it can be moved
        let data = self.data.clone();
        let name = self.name.clone();
        let stack_size = self.stack_size.clone();
        let status_sender = self.status_sender.clone();
        let handle = tokio::task::spawn_blocking(move || -> anyhow::Result<_> {
            let waker = task::noop_waker();
            let mut cx = Context::from_waker(&waker);
            let env = match Environment::new() {
                // We can't map errors here or it moves the send channel, so we
                // do it in a match
                Ok(e) => e,
                Err(e) => {
                    let message = "cannot create environment";
                    error!("{}: {:?}", message, e);
                    send(
                        status_sender.clone(),
                        name,
                        Status::Terminated {
                            failed: true,
                            message: message.into(),
                            timestamp: chrono::Utc::now(),
                        },
                        &mut cx,
                    );
                    return Err(anyhow::anyhow!("{}: {}", message, e));
                }
            };
            let rt = match env.create_runtime(stack_size) {
                // We can't map errors here or it moves the send channel, so we
                // do it in a match
                Ok(rt) => rt,
                Err(e) => {
                    let message = "cannot create runtime";
                    error!("{}: {:?}", message, e);
                    send(
                        status_sender.clone(),
                        name.clone(),
                        Status::Terminated {
                            failed: true,
                            message: message.into(),
                            timestamp: chrono::Utc::now(),
                        },
                        &mut cx,
                    );
                    return Err(anyhow::anyhow!("{}: {}", message, e));
                }
            };
            let module = match Module::parse(&env, &data.module_data) {
                // We can't map errors here or it moves the send channel, so we
                // do it in a match
                Ok(m) => m,
                Err(e) => {
                    let message = "cannot parse module";
                    error!("{}: {:?}", message, e);
                    send(
                        status_sender.clone(),
                        name.clone(),
                        Status::Terminated {
                            failed: true,
                            message: message.into(),
                            timestamp: chrono::Utc::now(),
                        },
                        &mut cx,
                    );
                    return Err(anyhow::anyhow!("{}: {}", message, e));
                }
            };
            let mut module = match rt.load_module(module) {
                // We can't map errors here or it moves the send channel, so we
                // do it in a match
                Ok(m) => m,
                Err(e) => {
                    let message = "cannot load module";
                    error!("{}: {:?}", message, e);
                    send(
                        status_sender.clone(),
                        name.clone(),
                        Status::Terminated {
                            failed: true,
                            message: message.into(),
                            timestamp: chrono::Utc::now(),
                        },
                        &mut cx,
                    );
                    return Err(anyhow::anyhow!("{}: {}", message, e));
                }
            };
            match module.link_wasi() {
                // We can't map errors here or it moves the send channel, so we
                // do it in a match
                Ok(_) => {}
                Err(e) => {
                    let message = "cannot link WASI";
                    error!("{}: {:?}", message, e);
                    send(
                        status_sender.clone(),
                        name.clone(),
                        Status::Terminated {
                            failed: true,
                            message: message.into(),
                            timestamp: chrono::Utc::now(),
                        },
                        &mut cx,
                    );
                    return Err(anyhow::anyhow!("{}: {}", message, e));
                }
            };
            let func = match module.find_function::<(), ()>("_start") {
                // We can't map errors here or it moves the send channel, so we
                // do it in a match
                Ok(f) => f,
                Err(e) => {
                    let message = "cannot find function '_start' in module";
                    error!("{}: {:?}", message, e);
                    send(
                        status_sender.clone(),
                        name.clone(),
                        Status::Terminated {
                            failed: true,
                            message: message.into(),
                            timestamp: chrono::Utc::now(),
                        },
                        &mut cx,
                    );
                    return Err(anyhow::anyhow!("{}: {}", message, e));
                }
            };
            match func.call() {
                // We can't map errors here or it moves the send channel, so we
                // do it in a match
                Ok(_) => {}
                Err(e) => {
                    let message = "unable to run module";
                    error!("{}: {:?}", message, e);
                    send(
                        status_sender.clone(),
                        name.clone(),
                        Status::Terminated {
                            failed: true,
                            message: message.into(),
                            timestamp: chrono::Utc::now(),
                        },
                        &mut cx,
                    );
                    return Err(anyhow::anyhow!("{}: {}", message, e));
                }
            };
            info!("module run complete");
            send(
                status_sender.clone(),
                name,
                Status::Terminated {
                    failed: false,
                    message: "Module run complete".into(),
                    timestamp: chrono::Utc::now(),
                },
                &mut cx,
            );
            Ok(())
        });
        Ok(handle)
    }
async fn spawn_wasm3 ( & self , _output_write : std :: fs :: File , ) -> anyhow :: Result < JoinHandle < anyhow :: Result < ( ) > > > { // Clone the module data Arc so it can be moved let data = self . data . clone ( ) ; let name = self . name . clone ( ) ; let stack_size = self . stack_size . clone ( ) ; let status_sender = self . status_sender . clone ( ) ; let handle = tokio :: task :: spawn_blocking ( move | | -> anyhow :: Result < _ > { let waker = task :: noop_waker ( ) ; let mut cx = Context :: from_waker ( & waker ) ; let env = match Environment :: new ( ) { // We can't map errors here or it moves the send channel, so we // do it in a match Ok ( e ) => e , Err ( e ) => { let message = " " ; error ! ( " " message e ) ; send ( status_sender . clone ( ) , name , Status :: Terminated { failed : true , message : message . into ( ) , timestamp : chrono :: Utc :: now ( ) , } , & mut cx , ) ; return Err ( anyhow :: anyhow ! ( " " message e ) ) ; } } ; let rt = match env . create_runtime ( stack_size ) { // We can't map errors here or it moves the send channel, so we // do it in a match Ok ( rt ) => rt , Err ( e ) => { let message = " " ; error ! ( " " message e ) ; send ( status_sender . clone ( ) , name . clone ( ) , Status :: Terminated { failed : true , message : message . into ( ) , timestamp : chrono :: Utc :: now ( ) , } , & mut cx , ) ; return Err ( anyhow :: anyhow ! ( " " message e ) ) ; } } ; let module = match Module :: parse ( & env , & data . module_data ) { // We can't map errors here or it moves the send channel, so we // do it in a match Ok ( m ) => m , Err ( e ) => { let message = " " ; error ! ( " " message e ) ; send ( status_sender . clone ( ) , name . clone ( ) , Status :: Terminated { failed : true , message : message . into ( ) , timestamp : chrono :: Utc :: now ( ) , } , & mut cx , ) ; return Err ( anyhow :: anyhow ! ( " " message e ) ) ; } } ; let mut module = match rt . load_module ( module ) { // We can't map errors here or it moves the send channel, so we // do it in a match Ok ( m ) => m , Err ( e ) => { let message = " " ; error ! ( " " message e ) ; send ( status_sender . clone ( ) , name . clone ( ) , Status :: Terminated { failed : true , message : message . into ( ) , timestamp : chrono :: Utc :: now ( ) , } , & mut cx , ) ; return Err ( anyhow :: anyhow ! ( " " message e ) ) ; } } ; match module . link_wasi ( ) { // We can't map errors here or it moves the send channel, so we // do it in a match Ok ( _ ) => { } Err ( e ) => { let message = " " ; error ! ( " " message e ) ; send ( status_sender . clone ( ) , name . clone ( ) , Status :: Terminated { failed : true , message : message . into ( ) , timestamp : chrono :: Utc :: now ( ) , } , & mut cx , ) ; return Err ( anyhow :: anyhow ! ( " " message e ) ) ; } } ; let func = match module . find_function :: < ( ) , ( ) > ( " " ) { // We can't map errors here or it moves the send channel, so we // do it in a match Ok ( f ) => f , Err ( e ) => { let message = " " ; error ! ( " " message e ) ; send ( status_sender . clone ( ) , name . clone ( ) , Status :: Terminated { failed : true , message : message . into ( ) , timestamp : chrono :: Utc :: now ( ) , } , & mut cx , ) ; return Err ( anyhow :: anyhow ! ( " " message e ) ) ; } } ; match func . call ( ) { // We can't map errors here or it moves the send channel, so we // do it in a match Ok ( _ ) => { } Err ( e ) => { let message = " " ; error ! ( " " message e ) ; send ( status_sender . clone ( ) , name . clone ( ) , Status :: Terminated { failed : true , message : message . into ( ) , timestamp : chrono :: Utc :: now ( ) , } , & mut cx , ) ; return Err ( anyhow :: anyhow ! ( " " message e ) ) ; } } ; info ! ( " " ) ; send ( status_sender . clone ( ) , name , Status :: Terminated { failed : false , message : " " . into ( ) , timestamp : chrono :: Utc :: now ( ) , } , & mut cx , ) ; Ok ( ( ) ) } ) ; Ok ( handle ) }
Spawns a running wasmtime instance with the given context and status
channel.
Spawns a running wasmtime instance with the given context and status channel .
&self
_output_write
std::fs::File