feat: allow process from external code
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
21a13f3444
commit
355587234e
@ -1,7 +1,7 @@
|
||||
use anyhow::Context;
|
||||
use component::churn_tasks::process::HostProcess;
|
||||
use futures::StreamExt;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::sync::Arc;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::sync::Mutex;
|
||||
use wasmtime::component::*;
|
||||
@ -10,10 +10,40 @@ use wasmtime_wasi::{DirPerms, FilePerms, WasiCtx, WasiCtxBuilder, WasiView};
|
||||
|
||||
wasmtime::component::bindgen!({
|
||||
path: "wit/world.wit",
|
||||
world: "churn",
|
||||
async: true
|
||||
//world: "churn",
|
||||
async: true,
|
||||
with: {
|
||||
"component:churn-tasks/process/process": CustomProcess
|
||||
}
|
||||
});
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CustomProcess {}
|
||||
impl CustomProcess {
|
||||
pub fn run(&self, args: Vec<String>) -> String {
|
||||
tracing::info!("calling function");
|
||||
|
||||
match args.split_first() {
|
||||
Some((item, rest)) => {
|
||||
let mut cmd = std::process::Command::new(item);
|
||||
match cmd.args(rest).output() {
|
||||
Ok(output) => std::str::from_utf8(&output.stdout)
|
||||
.expect("to be able to parse utf8")
|
||||
.to_string(),
|
||||
Err(e) => {
|
||||
tracing::error!("command failed with output: {e}");
|
||||
e.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
tracing::warn!("failed to call function because it is empty");
|
||||
panic!("failed to call function because it is empty")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PluginStore {
|
||||
inner: Arc<Mutex<InnerPluginStore>>,
|
||||
@ -53,6 +83,12 @@ impl InnerPluginStore {
|
||||
|
||||
// Add the command world (aka WASI CLI) to the linker
|
||||
wasmtime_wasi::add_to_linker_async(&mut linker).context("Failed to link command world")?;
|
||||
|
||||
component::churn_tasks::process::add_to_linker(
|
||||
&mut linker,
|
||||
|state: &mut ServerWasiView| state,
|
||||
)?;
|
||||
|
||||
let wasi_view = ServerWasiView::new();
|
||||
let store = Store::new(&engine, wasi_view);
|
||||
|
||||
@ -130,7 +166,8 @@ impl InnerPluginStore {
|
||||
);
|
||||
let instance = Churn::instantiate_async(&mut self.store, &component, &self.linker)
|
||||
.await
|
||||
.context("Failed to instantiate the example world")?;
|
||||
.context("Failed to instantiate the example world")
|
||||
.unwrap();
|
||||
|
||||
Ok(instance)
|
||||
}
|
||||
@ -139,6 +176,7 @@ impl InnerPluginStore {
|
||||
struct ServerWasiView {
|
||||
table: ResourceTable,
|
||||
ctx: WasiCtx,
|
||||
processes: ResourceTable,
|
||||
}
|
||||
|
||||
impl ServerWasiView {
|
||||
@ -153,7 +191,11 @@ impl ServerWasiView {
|
||||
.expect("to be able to open root")
|
||||
.build();
|
||||
|
||||
Self { table, ctx }
|
||||
Self {
|
||||
table,
|
||||
ctx,
|
||||
processes: ResourceTable::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,3 +208,32 @@ impl WasiView for ServerWasiView {
|
||||
&mut self.ctx
|
||||
}
|
||||
}
|
||||
|
||||
impl component::churn_tasks::process::Host for ServerWasiView {}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl HostProcess for ServerWasiView {
|
||||
async fn new(
|
||||
&mut self,
|
||||
) -> wasmtime::component::Resource<component::churn_tasks::process::Process> {
|
||||
self.processes.push(CustomProcess::default()).unwrap()
|
||||
}
|
||||
|
||||
async fn run_process(
|
||||
&mut self,
|
||||
self_: wasmtime::component::Resource<component::churn_tasks::process::Process>,
|
||||
inputs: wasmtime::component::__internal::Vec<String>,
|
||||
) -> String {
|
||||
let process = self.processes.get(&self_).unwrap();
|
||||
process.run(inputs)
|
||||
}
|
||||
|
||||
async fn drop(
|
||||
&mut self,
|
||||
rep: wasmtime::component::Resource<component::churn_tasks::process::Process>,
|
||||
) -> wasmtime::Result<()> {
|
||||
self.processes.delete(rep)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,12 @@
|
||||
package component:churn-tasks@0.1.0;
|
||||
|
||||
interface process {
|
||||
resource process {
|
||||
constructor();
|
||||
run-process: func(inputs: list<string>) -> string;
|
||||
}
|
||||
}
|
||||
|
||||
interface task {
|
||||
id: func() -> string;
|
||||
should-run: func() -> bool;
|
||||
@ -8,4 +15,5 @@ interface task {
|
||||
|
||||
world churn {
|
||||
export task;
|
||||
import process;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user