diff --git a/Cargo.toml b/Cargo.toml index f99b174..4124b97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.5.2" +version = "0.5.3" edition = "2021" publish = false authors = ["FastEdge Development Team"] @@ -57,6 +57,7 @@ pretty_env_logger = "0.5" runtime = { path = "crates/runtime", default-features = false } http-service = { path = "crates/http-service" } http-backend = { path = "crates/http-backend" } +dictionary = { path = "crates/dictionary" } hyper-tls = "0.6" hyper-util = { version = "0.1", features = ["client", "client-legacy", "http1", "tokio"] } http-body-util = "0.1" diff --git a/crates/dictionary/Cargo.toml b/crates/dictionary/Cargo.toml new file mode 100644 index 0000000..dad73a0 --- /dev/null +++ b/crates/dictionary/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "dictionary" +version.workspace = true +edition.workspace = true +publish.workspace = true +authors.workspace = true +description = "dictionary host function" + +[dependencies] +reactor = { path = "../reactor" } +anyhow = {workspace = true} +tracing = {workspace = true} +async-trait = {workspace = true} +wasmtime = {workspace = true} + +[lints] +workspace = true diff --git a/crates/dictionary/src/lib.rs b/crates/dictionary/src/lib.rs new file mode 100644 index 0000000..45e54cb --- /dev/null +++ b/crates/dictionary/src/lib.rs @@ -0,0 +1,47 @@ +use std::collections::HashMap; +use std::ops::{Deref, DerefMut}; +use async_trait::async_trait; +use reactor::gcore::fastedge::dictionary; + +#[derive(Clone)] +pub struct Dictionary{ + inner: HashMap +} + +#[async_trait] +impl dictionary::Host for Dictionary { + async fn get(&mut self, name: String) -> anyhow::Result> { + Ok(self.inner.get(&name).map(|v| v.to_string())) + } +} + +impl Default for Dictionary { + fn default() -> Self { + Self{ + inner: Default::default() + } + } +} + +impl Dictionary { + pub fn new() -> Self { + Self{ + inner: Default::default() + } + } +} + +impl Deref for Dictionary { + type Target = HashMap; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl DerefMut for Dictionary { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + diff --git a/crates/http-service/Cargo.toml b/crates/http-service/Cargo.toml index e9897cd..4bfc669 100644 --- a/crates/http-service/Cargo.toml +++ b/crates/http-service/Cargo.toml @@ -9,7 +9,6 @@ authors.workspace = true default = [] metrics = ["runtime/metrics"] stats = ["runtime/stats"] -#tls = ["tokio-rustls", "rustls-pemfile", "hyper-rustls", "rustls"] [dependencies] anyhow = { workspace = true } @@ -26,6 +25,7 @@ smol_str = { workspace = true } reactor = { path = "../reactor" } runtime = { path = "../runtime" } http-backend = { path = "../http-backend" } +dictionary = { path = "../dictionary" } nanoid = "0.4" bytesize = "1.3.0" futures = "0.3.30" diff --git a/crates/http-service/src/executor/mod.rs b/crates/http-service/src/executor/mod.rs index 6767b80..c230094 100644 --- a/crates/http-service/src/executor/mod.rs +++ b/crates/http-service/src/executor/mod.rs @@ -16,7 +16,7 @@ use runtime::store::StoreBuilder; use runtime::{App, InstancePre, WasmEngine}; use smol_str::SmolStr; use wasmtime_wasi::StdoutStream; - +use dictionary::Dictionary; use crate::state::HttpState; pub use wasi_http::WasiHttpExecutorImpl; @@ -52,6 +52,7 @@ pub struct HttpExecutorImpl { instance_pre: InstancePre>, store_builder: StoreBuilder, backend: Backend, + dictionary: Dictionary } #[async_trait] @@ -82,11 +83,13 @@ where instance_pre: InstancePre>, store_builder: StoreBuilder, backend: Backend, + dictionary: Dictionary, ) -> Self { Self { instance_pre, store_builder, backend, + dictionary, } } @@ -148,6 +151,7 @@ where uri: backend_uri, propagate_headers: parts.headers, propagate_header_names, + dictionary: self.dictionary.clone(), }; let mut store = store_builder.build(state)?; diff --git a/crates/http-service/src/executor/wasi_http.rs b/crates/http-service/src/executor/wasi_http.rs index 4c95d76..c0ba4ed 100644 --- a/crates/http-service/src/executor/wasi_http.rs +++ b/crates/http-service/src/executor/wasi_http.rs @@ -11,7 +11,7 @@ use hyper::body::{Body, Bytes}; use smol_str::ToSmolStr; use tracing::error; use wasmtime_wasi_http::{ WasiHttpView}; - +use dictionary::Dictionary; use http_backend::Backend; use runtime::store::StoreBuilder; use runtime::InstancePre; @@ -25,6 +25,7 @@ pub struct WasiHttpExecutorImpl { instance_pre: InstancePre>, store_builder: StoreBuilder, backend: Backend, + dictionary: Dictionary } #[async_trait] @@ -55,11 +56,13 @@ where instance_pre: InstancePre>, store_builder: StoreBuilder, backend: Backend, + dictionary: Dictionary, ) -> Self { Self { instance_pre, store_builder, backend, + dictionary, } } @@ -131,6 +134,7 @@ where uri: backend_uri, propagate_headers, propagate_header_names, + dictionary: self.dictionary.clone(), }; let mut store = store_builder.build(state).context("store build")?; diff --git a/crates/http-service/src/lib.rs b/crates/http-service/src/lib.rs index eb1b255..10731d1 100644 --- a/crates/http-service/src/lib.rs +++ b/crates/http-service/src/lib.rs @@ -131,13 +131,18 @@ where let linker = builder.component_linker_ref(); wasmtime_wasi_nn::wit::ML::add_to_linker(linker, |data| &mut data.as_mut().wasi_nn)?; // Allow re-importing of `wasi:clocks/wall-clock@0.2.0` + wasmtime_wasi::add_to_linker_async(linker)?; linker.allow_shadowing(true); wasmtime_wasi_http::proxy::add_to_linker(linker)?; - wasmtime_wasi::add_to_linker_async(linker)?; reactor::gcore::fastedge::http_client::add_to_linker(linker, |data| { &mut data.as_mut().http_backend })?; + + reactor::gcore::fastedge::dictionary::add_to_linker(linker, |data| { + &mut data.as_mut().dictionary + })?; + Ok(()) } } @@ -525,7 +530,7 @@ mod tests { use test_case::test_case; use wasmtime::component::Component; use wasmtime::{Engine, Module}; - + use dictionary::Dictionary; use http_backend::{Backend, BackendStrategy, FastEdgeConnector}; use runtime::logger::{Logger, NullAppender}; use runtime::service::ServiceBuilder; @@ -630,6 +635,11 @@ mod tests { cfg: &App, engine: &WasmEngine>, ) -> Result { + let mut dictionary = Dictionary::new(); + for (k, v) in cfg.env.iter() { + dictionary.insert(k.to_string(), v.to_string()); + } + let env = cfg.env.iter().collect::>(); let logger = self.make_logger(name.clone(), cfg); @@ -649,6 +659,7 @@ mod tests { instance_pre, store_builder, self.backend(), + dictionary, )) } } diff --git a/crates/http-service/src/state.rs b/crates/http-service/src/state.rs index e3e0f25..92afc2e 100644 --- a/crates/http-service/src/state.rs +++ b/crates/http-service/src/state.rs @@ -7,6 +7,7 @@ use runtime::BackendRequest; use smol_str::{SmolStr, ToSmolStr}; use tracing::instrument; use wasmtime_wasi_nn::WasiNnCtx; +use dictionary::Dictionary; pub struct HttpState { pub(super) wasi_nn: WasiNnCtx, @@ -14,6 +15,7 @@ pub struct HttpState { pub(super) uri: Uri, pub(super) propagate_headers: HeaderMap, pub(super) propagate_header_names: Vec, + pub(super) dictionary: Dictionary } impl BackendRequest for HttpState { diff --git a/crates/runtime/src/store.rs b/crates/runtime/src/store.rs index 6202ba0..7a54a81 100644 --- a/crates/runtime/src/store.rs +++ b/crates/runtime/src/store.rs @@ -197,7 +197,10 @@ impl StoreBuilder { ) -> Result> { let table = ResourceTable::new(); + debug!("ENV: {:?}", self.env); wasi_ctx_builder.envs(&self.env); + debug!("WasiNnCtxBuilder: {:?}", self.version); + //wasi_ctx_builder.inherit_env(); let logger = if let Some(mut logger) = self.logger { logger.extend(self.properties); @@ -206,9 +209,11 @@ impl StoreBuilder { } else { if cfg!(debug_assertions) { wasi_ctx_builder.inherit_stdout(); + wasi_ctx_builder.inherit_stderr(); } None }; + let wasi = match self.version { WasiVersion::Preview1 => Wasi::Preview1(wasi_ctx_builder.build_p1()), WasiVersion::Preview2 => Wasi::Preview2(wasi_ctx_builder.build()), diff --git a/sdk b/sdk index 7de469d..5e07465 160000 --- a/sdk +++ b/sdk @@ -1 +1 @@ -Subproject commit 7de469d5d6ca3a777eb2bfae7435b7daa976ab6a +Subproject commit 5e0746539c11eb3d72bef23b327d7b4148515aa0 diff --git a/src/main.rs b/src/main.rs index 251e168..67c06b2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use bytesize::ByteSize; +use bytesize::{ByteSize, MB}; use clap::{Args, Parser, Subcommand}; use http::{Request, Response}; use http_backend::{Backend, BackendStrategy}; @@ -28,6 +28,7 @@ use std::path::PathBuf; use std::time::Duration; use wasmtime::component::Component; use wasmtime::{Engine, Module}; +use dictionary::Dictionary; #[derive(Debug, Parser)] #[command(name = "cli")] @@ -106,7 +107,7 @@ async fn main() -> anyhow::Result<()> { let cli_app = App { binary_id: 0, max_duration: run.max_duration.map(|m| m / 10).unwrap_or(60000), - mem_limit: run.mem_limit.unwrap_or(u32::MAX as usize), + mem_limit: run.mem_limit.unwrap_or((128 * MB) as usize), env: run.envs.unwrap_or_default().into_iter().collect(), rsp_headers: Default::default(), log: Default::default(), @@ -235,6 +236,11 @@ impl ExecutorFactory>> for CliContext { app: &App, engine: &WasmEngine>>, ) -> anyhow::Result { + let mut dictionary = Dictionary::new(); + for (k, v) in app.env.iter() { + dictionary.insert(k.to_string(), v.to_string()); + } + let env = app.env.iter().collect::>(); let logger = self.make_logger(name, app); @@ -254,12 +260,14 @@ impl ExecutorFactory>> for CliContext { instance_pre, store_builder, self.backend(), + dictionary ))) } else { Ok(CliExecutor::Http(HttpExecutorImpl::new( instance_pre, store_builder, self.backend(), + dictionary ))) } }