cardinal_wasm_plugins/
runner.rs

1use crate::host::{HostFunctionBuilder, HostImportHandle};
2use crate::instance::InstancePool;
3use crate::plugin::WasmPlugin;
4use crate::SharedExecutionContext;
5use cardinal_errors::CardinalError;
6use std::sync::Arc;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum ExecutionPhase {
10    Inbound,
11    Outbound,
12}
13
14#[derive(Debug)]
15pub struct ExecutionResult {
16    pub should_continue: bool,
17    pub execution_context: SharedExecutionContext,
18}
19
20pub struct WasmRunner {
21    pool: Arc<InstancePool>,
22}
23
24impl WasmRunner {
25    pub fn new(
26        plugin: &Arc<WasmPlugin>,
27        phase: ExecutionPhase,
28        host_imports: Option<&[HostImportHandle]>,
29    ) -> Self {
30        let dynamic = host_imports
31            .map(|imports| imports.to_vec())
32            .unwrap_or_default();
33
34        let pool = InstancePool::new(plugin.clone(), phase, dynamic);
35        Self {
36            pool: Arc::new(pool),
37        }
38    }
39
40    pub fn run_raw(
41        &self,
42        shared_ctx: SharedExecutionContext,
43    ) -> Result<ExecutionResult, CardinalError> {
44        let mut guard = self.pool.acquire(shared_ctx.clone())?;
45        let instance = guard.instance();
46
47        let body = shared_ctx.read().request().body().cloned();
48        let body_slice = body.as_ref().map(|bytes| bytes.as_ref());
49
50        let (ptr, len) = instance.write_body(body_slice)?;
51        let decision = instance.call_handle(ptr, len)?;
52
53        Ok(ExecutionResult {
54            should_continue: decision == 1,
55            execution_context: shared_ctx,
56        })
57    }
58
59    pub fn run(
60        &self,
61        shared_ctx: SharedExecutionContext,
62    ) -> Result<ExecutionResult, CardinalError> {
63        let run = self.run_raw(shared_ctx);
64        match run {
65            Ok(result) => Ok(result),
66            Err(e) => {
67                tracing::error!("Failed to run plugin: {}", e);
68                Err(e)
69            }
70        }
71    }
72}
73
74pub fn host_import_from_builder<N, S>(
75    namespace: N,
76    name: S,
77    builder: HostFunctionBuilder,
78) -> HostImportHandle
79where
80    N: Into<String>,
81    S: Into<String>,
82{
83    Arc::new(crate::host::DynamicHostImport::new(
84        namespace, name, builder,
85    ))
86}