This commit is contained in:
@@ -18,6 +18,7 @@ impl Plan {
|
||||
Ok(vec![
|
||||
AptTask::new().into_task(),
|
||||
PluginTask::new("alloy@0.1.0", self.store.clone()).into_task(),
|
||||
PluginTask::new("dev_packages@0.1.0", self.store.clone()).into_task(),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@ use wasmtime::component::*;
|
||||
use wasmtime::{Config, Engine, Store};
|
||||
use wasmtime_wasi::{DirPerms, FilePerms, WasiCtx, WasiCtxBuilder, WasiView};
|
||||
|
||||
use super::agent_state::State;
|
||||
use super::config::AgentConfig;
|
||||
|
||||
wasmtime::component::bindgen!({
|
||||
@@ -16,10 +15,13 @@ wasmtime::component::bindgen!({
|
||||
//world: "churn",
|
||||
async: true,
|
||||
with: {
|
||||
"component:churn-tasks/process/process": CustomProcess
|
||||
"component:churn-tasks/process/process": CustomProcess,
|
||||
"component:churn-tasks/http/client": http::HttpClient
|
||||
}
|
||||
});
|
||||
|
||||
mod http;
|
||||
|
||||
pub struct CustomProcess {
|
||||
agent_config: AgentConfig,
|
||||
}
|
||||
@@ -75,6 +77,10 @@ impl PluginStore {
|
||||
|
||||
pub async fn execute(&self, plugin: &str) -> anyhow::Result<()> {
|
||||
let mut inner = self.inner.lock().await;
|
||||
|
||||
// FIXME: hack to avoid memory leak issues from instantiating plugins
|
||||
*inner = InnerPluginStore::new(inner.agent_config.clone())?;
|
||||
|
||||
inner.execute(plugin).await
|
||||
}
|
||||
}
|
||||
@@ -83,6 +89,7 @@ pub struct InnerPluginStore {
|
||||
store: wasmtime::Store<ServerWasiView>,
|
||||
linker: wasmtime::component::Linker<ServerWasiView>,
|
||||
engine: wasmtime::Engine,
|
||||
agent_config: AgentConfig,
|
||||
}
|
||||
|
||||
impl InnerPluginStore {
|
||||
@@ -101,13 +108,18 @@ impl InnerPluginStore {
|
||||
|state: &mut ServerWasiView| state,
|
||||
)?;
|
||||
|
||||
let wasi_view = ServerWasiView::new(agent_config);
|
||||
component::churn_tasks::http::add_to_linker(&mut linker, |state: &mut ServerWasiView| {
|
||||
state
|
||||
})?;
|
||||
|
||||
let wasi_view = ServerWasiView::new(agent_config.clone());
|
||||
let store = Store::new(&engine, wasi_view);
|
||||
|
||||
Ok(Self {
|
||||
store,
|
||||
linker,
|
||||
engine,
|
||||
agent_config,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -124,6 +136,8 @@ impl InnerPluginStore {
|
||||
pub async fn execute(&mut self, plugin: &str) -> anyhow::Result<()> {
|
||||
let plugin = self.ensure_plugin(plugin).await?;
|
||||
|
||||
self.store.gc_async().await;
|
||||
|
||||
if plugin
|
||||
.interface0
|
||||
.call_should_run(&mut self.store)
|
||||
@@ -205,6 +219,7 @@ struct ServerWasiView {
|
||||
table: ResourceTable,
|
||||
ctx: WasiCtx,
|
||||
processes: ResourceTable,
|
||||
clients: ResourceTable,
|
||||
agent_config: AgentConfig,
|
||||
}
|
||||
|
||||
@@ -215,6 +230,7 @@ impl ServerWasiView {
|
||||
let ctx = WasiCtxBuilder::new()
|
||||
.inherit_stdio()
|
||||
.inherit_stdout()
|
||||
.inherit_env()
|
||||
.inherit_stderr()
|
||||
.inherit_network()
|
||||
.preopened_dir("/", "/", DirPerms::all(), FilePerms::all())
|
||||
@@ -225,6 +241,7 @@ impl ServerWasiView {
|
||||
table,
|
||||
ctx,
|
||||
processes: ResourceTable::default(),
|
||||
clients: ResourceTable::default(),
|
||||
agent_config,
|
||||
}
|
||||
}
|
||||
@@ -279,3 +296,33 @@ impl HostProcess for ServerWasiView {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl component::churn_tasks::http::Host for ServerWasiView {}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl component::churn_tasks::http::HostClient for ServerWasiView {
|
||||
async fn new(&mut self) -> wasmtime::component::Resource<component::churn_tasks::http::Client> {
|
||||
self.clients.push(http::HttpClient::new()).unwrap()
|
||||
}
|
||||
|
||||
async fn get(
|
||||
&mut self,
|
||||
self_: wasmtime::component::Resource<component::churn_tasks::http::Client>,
|
||||
url: wasmtime::component::__internal::String,
|
||||
) -> Vec<u8> {
|
||||
let process = self.clients.get(&self_).unwrap();
|
||||
process
|
||||
.get(&url)
|
||||
.await
|
||||
.expect("to be able to make http call")
|
||||
}
|
||||
|
||||
async fn drop(
|
||||
&mut self,
|
||||
rep: wasmtime::component::Resource<component::churn_tasks::http::Client>,
|
||||
) -> wasmtime::Result<()> {
|
||||
self.clients.delete(rep)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
12
crates/churn/src/agent/plugins/http.rs
Normal file
12
crates/churn/src/agent/plugins/http.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
pub struct HttpClient {}
|
||||
|
||||
impl HttpClient {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
pub async fn get(&self, url: &str) -> anyhow::Result<Vec<u8>> {
|
||||
let bytes = reqwest::get(url).await?.bytes().await?;
|
||||
Ok(bytes.into())
|
||||
}
|
||||
}
|
@@ -8,6 +8,13 @@ interface process {
|
||||
}
|
||||
}
|
||||
|
||||
interface http {
|
||||
resource client {
|
||||
constructor();
|
||||
get: func(url: string) -> list<u8>;
|
||||
}
|
||||
}
|
||||
|
||||
interface task {
|
||||
id: func() -> string;
|
||||
should-run: func() -> bool;
|
||||
@@ -17,4 +24,5 @@ interface task {
|
||||
world churn {
|
||||
export task;
|
||||
import process;
|
||||
import http;
|
||||
}
|
||||
|
Reference in New Issue
Block a user