wasmer_wasix/runners/dcgi/
factory.rs1use std::sync::{Arc, Mutex};
2
3use virtual_fs::Pipe;
4use wasmer_wasix_types::types::{__WASI_STDERR_FILENO, __WASI_STDIN_FILENO, __WASI_STDOUT_FILENO};
5
6use crate::{
7 WasiStateCreationError,
8 runners::wcgi::{CreateEnvConfig, CreateEnvResult, RecycleEnvConfig},
9 state::conv_env_vars,
10};
11
12use super::*;
13
14#[derive(Debug, Default)]
15struct State {
16 instance: Option<DcgiInstance>,
18}
19
20#[derive(Debug, Clone, Default)]
23pub struct DcgiInstanceFactory {
24 state: Arc<Mutex<State>>,
25}
26
27impl DcgiInstanceFactory {
28 pub fn new() -> Self {
29 Default::default()
30 }
31
32 pub async fn release(&self, conf: RecycleEnvConfig) {
33 let mut state = self.state.lock().unwrap();
34 state.instance.replace(DcgiInstance {
35 env: conf.env,
36 });
39 }
40
41 pub async fn acquire(&self, conf: &mut CreateEnvConfig) -> Option<CreateEnvResult> {
42 let mut state = self.state.lock().unwrap();
43 if let Some(inst) = state.instance.take() {
44 tracing::debug!("attempting to reinitialize DCGI instance");
45 match convert_instance(inst, conf) {
46 Ok(converted) => return Some(converted),
47 Err(err) => {
48 tracing::warn!("failed to reinitialize DCGI instance - {}", err);
49 }
50 }
51 }
52
53 None
54 }
55}
56
57fn convert_instance(
58 inst: DcgiInstance,
59 conf: &mut CreateEnvConfig,
60) -> anyhow::Result<CreateEnvResult> {
61 let mut env = inst.env;
62
63 let (req_body_sender, req_body_receiver) = Pipe::channel();
64 let (res_body_sender, res_body_receiver) = Pipe::channel();
65 let (stderr_sender, stderr_receiver) = Pipe::channel();
66
67 env.reinit()?;
68
69 *env.state.envs.lock().unwrap() = conv_env_vars(
72 conf.env
73 .iter()
74 .map(|(k, v)| (k.clone(), v.as_bytes().to_vec()))
75 .collect(),
76 );
77
78 env.state
81 .fs
82 .swap_file(__WASI_STDIN_FILENO, Box::new(req_body_receiver))
83 .map_err(WasiStateCreationError::FileSystemError)?;
84
85 env.state
86 .fs
87 .swap_file(__WASI_STDOUT_FILENO, Box::new(res_body_sender))
88 .map_err(WasiStateCreationError::FileSystemError)?;
89
90 env.state
91 .fs
92 .swap_file(__WASI_STDERR_FILENO, Box::new(stderr_sender))
93 .map_err(WasiStateCreationError::FileSystemError)?;
94
95 Ok(CreateEnvResult {
96 env,
97 memory: None,
99 body_sender: req_body_sender,
100 body_receiver: res_body_receiver,
101 stderr_receiver,
102 })
103}