Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
600 changes: 325 additions & 275 deletions Cargo.lock

Large diffs are not rendered by default.

11 changes: 8 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ tokio = { version = "1", features = ["full"] }
tokio-util = { version = "0.7", features = ["codec"] }
tracing = "0.1"
hyper = { version = "1", features = ["full"] }
http = "1.2.0"
http = "1.3.1"
async-trait = "0.1"
wasmtime = { version = "29.0.1", git = "https://github.com/G-Core/wasmtime.git", branch = "wasi_nn_candle_backend"}
wasmtime-wasi = { version = "29.0.1", git = "https://github.com/G-Core/wasmtime.git", branch = "wasi_nn_candle_backend"}
wasi-common = { version = "29.0.1", git = "https://github.com/G-Core/wasmtime.git", branch = "wasi_nn_candle_backend"}
wasmtime-wasi-nn = { version = "29.0.1", features = ["openvino", "candle"], git = "https://github.com/G-Core/wasmtime.git", branch = "wasi_nn_candle_backend"}
wasmtime-wasi-http = { version = "29.0.1", git = "https://github.com/G-Core/wasmtime.git", branch = "wasi_nn_candle_backend"}
wasmtime-environ = { version = "29.0.1", git = "https://github.com/G-Core/wasmtime.git", branch = "wasi_nn_candle_backend"}
bytesize = "2.0.1"

clap = { version = "4", features = ["derive"] }
moka = { version = "0.12", features = ["sync"] }
Expand Down Expand Up @@ -59,10 +60,14 @@ http-service = { path = "crates/http-service" }
http-backend = { path = "crates/http-backend" }
dictionary = { path = "crates/dictionary" }
secret = { path = "crates/secret" }
key-value-store = { path = "crates/key-value-store" }
hyper-tls = "0.6"
hyper-util = { version = "0.1", features = ["client", "client-legacy", "http1", "tokio"] }
http-body-util = "0.1"
bytesize = "1.3.0"
bytesize = { workspace = true}

[target.'cfg(target_family = "unix")'.dependencies]
shellflip = "2.1.1"
shellflip = "2.1.2"

[patch.crates-io]
half = { git = 'https://github.com/starkat99/half-rs.git', tag = "v2.4.1" }
4 changes: 2 additions & 2 deletions crates/http-backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ tracing = {workspace = true}
hyper = { workspace = true }
tokio = { workspace = true }
hyper-util = { version = "0.1.10", features = ["client", "client-legacy", "http1", "tokio"] }
http-body-util = "0.1.2"
pin-project = "1.1.8"
http-body-util = "0.1.3"
pin-project = "1.1.10"
tower-service = "0.3.3"
smol_str = {workspace = true}

Expand Down
6 changes: 3 additions & 3 deletions crates/http-service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ http-backend = { path = "../http-backend" }
dictionary = { path = "../dictionary" }
secret = { path = "../secret" }
nanoid = "0.4"
bytesize = "1.3.0"
bytesize = { workspace = true }
async-trait = "0.1"
hyper-util = { version = "0.1", features = ["server", "server-graceful"] }
http-body-util = "0.1"
bytes = "1.10"

[target.'cfg(target_family = "unix")'.dependencies]
shellflip = "2.1.1"
shellflip = "2.1.2"

[dev-dependencies]
claims = "0.8"
test-case = "3.3"
tracing-test = "0.2"

key-value-store = { path = "../key-value-store" }
69 changes: 29 additions & 40 deletions crates/http-service/src/executor/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,23 @@ use http_body_util::{BodyExt, Full};
use hyper::body::Body;
use reactor::gcore::fastedge;
use runtime::{store::StoreBuilder, InstancePre};
use secret::{Secret, SecretStrategy};
use std::time::{Duration, Instant};
use wasmtime_wasi::StdoutStream;
use wasmtime_wasi_http::body::HyperOutgoingBody;

/// Execute context used by ['HttpService']
#[derive(Clone)]
pub struct HttpExecutorImpl<C, T: SecretStrategy> {
instance_pre: InstancePre<HttpState<C, T>>,
pub struct HttpExecutorImpl<C> {
instance_pre: InstancePre<HttpState<C>>,
store_builder: StoreBuilder,
backend: Backend<C>,
dictionary: Dictionary,
secret: Secret<T>,
}

#[async_trait]
impl<C, T> HttpExecutor for HttpExecutorImpl<C, T>
impl<C> HttpExecutor for HttpExecutorImpl<C>
where
C: Clone + Send + Sync + 'static,
T: SecretStrategy + Clone + Send + Sync,
{
async fn execute<B, R>(
&self,
Expand Down Expand Up @@ -93,7 +90,6 @@ where
propagate_headers: parts.headers,
propagate_header_names,
dictionary: self.dictionary.clone(),
secret: self.secret.clone(),
};

let mut store = store_builder.build(state)?;
Expand Down Expand Up @@ -147,24 +143,21 @@ where
}
}

impl<C, T> HttpExecutorImpl<C, T>
impl<C> HttpExecutorImpl<C>
where
C: Clone + Send + Sync + 'static,
T: SecretStrategy + Clone + Send,
{
pub fn new(
instance_pre: InstancePre<HttpState<C, T>>,
instance_pre: InstancePre<HttpState<C>>,
store_builder: StoreBuilder,
backend: Backend<C>,
dictionary: Dictionary,
secret: Secret<T>,
) -> Self {
Self {
instance_pre,
store_builder,
backend,
dictionary,
secret,
}
}
}
Expand Down Expand Up @@ -195,15 +188,16 @@ mod tests {
use dictionary::Dictionary;
use http_backend::{Backend, BackendStrategy, FastEdgeConnector};
use http_body_util::Empty;
use runtime::app::Status;
use key_value_store::KeyValueStore;
use runtime::app::{KvStoreOption, SecretOption, Status};
use runtime::logger::{Logger, NullAppender};
use runtime::service::ServiceBuilder;
use runtime::util::stats::{StatRow, StatsWriter};
use runtime::{
componentize_if_necessary, App, ContextT, PreCompiledLoader, Router, WasiVersion,
WasmConfig, WasmEngine,
};
use secret::Secret;
use secret::SecretStore;
use smol_str::{SmolStr, ToSmolStr};
use std::collections::HashMap;
use wasmtime::component::Component;
Expand Down Expand Up @@ -237,6 +231,14 @@ mod tests {
fn engine_ref(&self) -> &Engine {
&self.engine
}

fn make_secret_store(&self, _secrets: &Vec<SecretOption>) -> anyhow::Result<SecretStore> {
todo!()
}

fn make_key_value_store(&self, _stores: &Vec<KvStoreOption>) -> KeyValueStore {
todo!()
}
}

static DUMMY_SAMPLE: &[u8] = include_bytes!("../fixtures/dummy.wasm");
Expand Down Expand Up @@ -278,34 +280,19 @@ mod tests {
}
}

#[derive(Clone)]
struct TestSecret;

impl SecretStrategy for TestSecret {
fn get(&self, _key: String) -> anyhow::Result<Option<Vec<u8>>> {
Ok(Some(b"secret".to_vec()))
}

fn get_effective_at(&self, _key: String, _at: u64) -> anyhow::Result<Option<Vec<u8>>> {
Ok(Some(b"secret".to_vec()))
}
}

impl ExecutorFactory<HttpState<FastEdgeConnector, TestSecret>> for TestContext {
type Executor = HttpExecutorImpl<FastEdgeConnector, TestSecret>;
impl ExecutorFactory<HttpState<FastEdgeConnector>> for TestContext {
type Executor = HttpExecutorImpl<FastEdgeConnector>;

fn get_executor(
&self,
name: SmolStr,
cfg: &App,
engine: &WasmEngine<HttpState<FastEdgeConnector, TestSecret>>,
engine: &WasmEngine<HttpState<FastEdgeConnector>>,
) -> anyhow::Result<Self::Executor> {
let mut dictionary = Dictionary::new();
for (k, v) in cfg.env.iter() {
dictionary.insert(k.to_string(), v.to_string());
}
let secret = Secret::new(TestSecret);

let env = cfg.env.iter().collect::<Vec<(&SmolStr, &SmolStr)>>();

let logger = self.make_logger(name.clone(), cfg);
Expand All @@ -326,7 +313,6 @@ mod tests {
store_builder,
self.backend(),
dictionary,
secret,
))
}
}
Expand All @@ -348,6 +334,7 @@ mod tests {
status,
debug_until: None,
secrets: vec![],
kv_stores: vec![],
})
}

Expand Down Expand Up @@ -388,7 +375,7 @@ mod tests {
engine: make_engine(),
};

let http_service: HttpService<TestContext, TestSecret> =
let http_service: HttpService<TestContext> =
assert_ok!(ServiceBuilder::new(context).build());

let res = assert_ok!(http_service.handle_request("1", req).await);
Expand Down Expand Up @@ -430,6 +417,7 @@ mod tests {
status: Status::Enabled,
debug_until: None,
secrets: vec![],
kv_stores: vec![],
});

let context = TestContext {
Expand All @@ -438,7 +426,7 @@ mod tests {
engine: make_engine(),
};

let http_service: HttpService<TestContext, TestSecret> =
let http_service: HttpService<TestContext> =
assert_ok!(ServiceBuilder::new(context).build());

let res = assert_ok!(http_service.handle_request("2", req).await);
Expand Down Expand Up @@ -479,6 +467,7 @@ mod tests {
status: Status::Enabled,
debug_until: None,
secrets: vec![],
kv_stores: vec![],
});

let context = TestContext {
Expand All @@ -487,7 +476,7 @@ mod tests {
engine: make_engine(),
};

let http_service: HttpService<TestContext, TestSecret> =
let http_service: HttpService<TestContext> =
assert_ok!(ServiceBuilder::new(context).build());

let res = assert_ok!(http_service.handle_request("3", req).await);
Expand Down Expand Up @@ -521,7 +510,7 @@ mod tests {
engine: make_engine(),
};

let http_service: HttpService<TestContext, TestSecret> =
let http_service: HttpService<TestContext> =
assert_ok!(ServiceBuilder::new(context).build());
let res = assert_ok!(http_service.handle_request("4", req).await);
assert_eq!(StatusCode::NOT_FOUND, res.status());
Expand All @@ -547,7 +536,7 @@ mod tests {
engine: make_engine(),
};

let http_service: HttpService<TestContext, TestSecret> =
let http_service: HttpService<TestContext> =
assert_ok!(ServiceBuilder::new(context).build());
let res = assert_ok!(http_service.handle_request("5", req).await);
assert_eq!(StatusCode::NOT_FOUND, res.status());
Expand All @@ -573,7 +562,7 @@ mod tests {
engine: make_engine(),
};

let http_service: HttpService<TestContext, TestSecret> =
let http_service: HttpService<TestContext> =
assert_ok!(ServiceBuilder::new(context).build());
let res = assert_ok!(http_service.handle_request("6", req).await);
assert_eq!(StatusCode::TOO_MANY_REQUESTS, res.status());
Expand All @@ -599,7 +588,7 @@ mod tests {
engine: make_engine(),
};

let http_service: HttpService<TestContext, TestSecret> =
let http_service: HttpService<TestContext> =
assert_ok!(ServiceBuilder::new(context).build());
let res = assert_ok!(http_service.handle_request("7", req).await);
assert_eq!(StatusCode::NOT_ACCEPTABLE, res.status());
Expand Down
17 changes: 5 additions & 12 deletions crates/http-service/src/executor/wasi_http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,23 @@ use http_backend::Backend;
use http_body_util::{BodyExt, Full};
use hyper::body::Body;
use runtime::{store::StoreBuilder, InstancePre};
use secret::{Secret, SecretStrategy};
use wasmtime_wasi_http::bindings::http::types::Scheme;
use wasmtime_wasi_http::bindings::ProxyPre;
use wasmtime_wasi_http::{body::HyperOutgoingBody, WasiHttpView};

/// Execute context used by ['HttpService']
#[derive(Clone)]
pub struct WasiHttpExecutorImpl<C, T: SecretStrategy> {
instance_pre: InstancePre<HttpState<C, T>>,
pub struct WasiHttpExecutorImpl<C> {
instance_pre: InstancePre<HttpState<C>>,
store_builder: StoreBuilder,
backend: Backend<C>,
dictionary: Dictionary,
secret: Secret<T>,
}

#[async_trait]
impl<C, T> HttpExecutor for WasiHttpExecutorImpl<C, T>
impl<C> HttpExecutor for WasiHttpExecutorImpl<C>
where
C: Clone + Send + Sync + 'static,
T: SecretStrategy + Clone + Send + Sync + 'static,
{
async fn execute<B, R>(
&self,
Expand Down Expand Up @@ -103,7 +100,6 @@ where
propagate_headers,
propagate_header_names,
dictionary: self.dictionary.clone(),
secret: self.secret.clone(),
};

let mut store = store_builder.build(state).context("store build")?;
Expand Down Expand Up @@ -190,24 +186,21 @@ where
}
}

impl<C, T> WasiHttpExecutorImpl<C, T>
impl<C> WasiHttpExecutorImpl<C>
where
C: Clone + Send + Sync + 'static,
T: SecretStrategy + Clone + Send + 'static,
{
pub fn new(
instance_pre: InstancePre<HttpState<C, T>>,
instance_pre: InstancePre<HttpState<C>>,
store_builder: StoreBuilder,
backend: Backend<C>,
dictionary: Dictionary,
secret: Secret<T>,
) -> Self {
Self {
instance_pre,
store_builder,
backend,
dictionary,
secret,
}
}
}
Expand Down
Loading