1use std::sync::mpsc;
2
3use anyhow::{anyhow, bail, Context};
4use log::debug;
5use wasmtime::Engine;
6
7pub enum ProgramOperation {
9 Resume,
11 Terminate,
13}
14
15pub struct WasmProgramHandle {
17 operation_tx: mpsc::Sender<ProgramOperation>,
18 paused: bool,
19 engine: Engine,
20}
21
22impl WasmProgramHandle {
23 pub(crate) fn new(operation_tx: mpsc::Sender<ProgramOperation>, engine: Engine) -> Self {
24 Self {
25 operation_tx,
26 engine,
27 paused: false,
28 }
29 }
30 pub fn pause(&mut self) -> anyhow::Result<()> {
33 if self.paused {
34 bail!("Already paused!");
35 }
36 self.engine.increment_epoch();
37 self.paused = true;
38 Ok(())
39 }
40 pub fn resume(&mut self) -> anyhow::Result<()> {
43 if !self.paused {
44 bail!("Already running!");
45 }
46 self.operation_tx
47 .send(ProgramOperation::Resume)
48 .with_context(|| anyhow!("Failed to send resume operation"))?;
49 self.paused = false;
50 Ok(())
51 }
52 pub fn terminate(self) -> anyhow::Result<()> {
55 debug!("Terminating wasm program");
56 self.engine.increment_epoch();
57 self.operation_tx
58 .send(ProgramOperation::Terminate)
59 .with_context(|| anyhow!("Failed to send terminate operation"))?;
60 Ok(())
61 }
62}