Skip to content

Commit

Permalink
refactor: introduce p2 module
Browse files Browse the repository at this point in the history
Signed-off-by: Roman Volosatovs <[email protected]>
  • Loading branch information
rvolosatovs committed Jan 22, 2025
1 parent 5d6cd8c commit 815b81a
Show file tree
Hide file tree
Showing 111 changed files with 641 additions and 612 deletions.
8 changes: 4 additions & 4 deletions ci/vendor-wit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ make_vendor() {

cache_dir=$(mktemp -d)

make_vendor "wasi" "
make_vendor "wasi/src/p2" "
[email protected]
[email protected]
[email protected]
Expand All @@ -45,7 +45,7 @@ make_vendor "wasi" "
[email protected]
"

make_vendor "wasi-http" "
make_vendor "wasi-http/src/p2" "
[email protected]
[email protected]
[email protected]
Expand All @@ -55,9 +55,9 @@ make_vendor "wasi-http" "
[email protected]
"

make_vendor "wasi-config" "config@f4d699b"
make_vendor "wasi-config/src/p2" "config@f4d699b"

make_vendor "wasi-keyvalue" "keyvalue@219ea36"
make_vendor "wasi-keyvalue/src/p2" "keyvalue@219ea36"

rm -rf $cache_dir

Expand Down
2 changes: 1 addition & 1 deletion crates/test-programs/src/bin/api_reactor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::sync::{Mutex, MutexGuard};

wit_bindgen::generate!({
world: "test-reactor",
path: "../wasi/wit",
path: "../wasi/src/p2/wit",
generate_all,
});

Expand Down
8 changes: 4 additions & 4 deletions crates/test-programs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ wit_bindgen::generate!({
}
",
path: [
"../wasi-http/wit",
"../wasi-config/wit",
"../wasi-keyvalue/wit",
"../wasi-http/src/p2/wit",
"../wasi-config/src/p2/wit",
"../wasi-keyvalue/src/p2/wit",
],
world: "wasmtime:test/test",
features: ["cli-exit-with-code"],
Expand All @@ -26,7 +26,7 @@ wit_bindgen::generate!({

pub mod proxy {
wit_bindgen::generate!({
path: "../wasi-http/wit",
path: "../wasi-http/src/p2/wit",
world: "wasi:http/proxy",
default_bindings_module: "test_programs::proxy",
pub_export_macro: true,
Expand Down
36 changes: 3 additions & 33 deletions crates/wasi-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,11 @@
#![deny(missing_docs)]

use anyhow::Result;
use std::collections::HashMap;

mod gen_ {
wasmtime::component::bindgen!({
path: "wit",
world: "wasi:config/imports",
trappable_imports: true,
});
}
use self::gen_::wasi::config::store as generated;
pub mod p2;
#[doc(inline)]
pub use p2::*;

/// Capture the state necessary for use in the `wasi-config` API implementation.
#[derive(Default)]
Expand Down Expand Up @@ -123,27 +117,3 @@ impl<'a> WasiConfig<'a> {
Self { vars }
}
}

impl generated::Host for WasiConfig<'_> {
fn get(&mut self, key: String) -> Result<Result<Option<String>, generated::Error>> {
Ok(Ok(self.vars.0.get(&key).map(|s| s.to_owned())))
}

fn get_all(&mut self) -> Result<Result<Vec<(String, String)>, generated::Error>> {
Ok(Ok(self
.vars
.0
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect()))
}
}

/// Add all the `wasi-config` world's interfaces to a [`wasmtime::component::Linker`].
pub fn add_to_linker<T>(
l: &mut wasmtime::component::Linker<T>,
f: impl Fn(&mut T) -> WasiConfig<'_> + Send + Sync + Copy + 'static,
) -> Result<()> {
generated::add_to_linker_get_host(l, f)?;
Ok(())
}
36 changes: 36 additions & 0 deletions crates/wasi-config/src/p2/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! Implementation of wasip2 version of `wasi:config` package
mod gen_ {
wasmtime::component::bindgen!({
path: "src/p2/wit",
world: "wasi:config/imports",
trappable_imports: true,
});
}
use self::gen_::wasi::config::store as generated;

use crate::WasiConfig;

impl generated::Host for WasiConfig<'_> {
fn get(&mut self, key: String) -> anyhow::Result<Result<Option<String>, generated::Error>> {
Ok(Ok(self.vars.0.get(&key).map(|s| s.to_owned())))
}

fn get_all(&mut self) -> anyhow::Result<Result<Vec<(String, String)>, generated::Error>> {
Ok(Ok(self
.vars
.0
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect()))
}
}

/// Add all the `wasi-config` world's interfaces to a [`wasmtime::component::Linker`].
pub fn add_to_linker<T>(
l: &mut wasmtime::component::Linker<T>,
f: impl Fn(&mut T) -> WasiConfig<'_> + Send + Sync + Copy + 'static,
) -> anyhow::Result<()> {
generated::add_to_linker_get_host(l, f)?;
Ok(())
}
File renamed without changes.
2 changes: 1 addition & 1 deletion crates/wasi-http/src/body.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Implementation of the `wasi:http/types` interface's various body types.
use crate::{bindings::http::types, types::FieldMap};
use crate::{p2::bindings::http::types, types::FieldMap};
use anyhow::anyhow;
use bytes::Bytes;
use http_body::{Body, Frame};
Expand Down
2 changes: 1 addition & 1 deletion crates/wasi-http/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::bindings::http::types::ErrorCode;
use crate::p2::bindings::http::types::ErrorCode;
use std::error::Error;
use std::fmt;
use wasmtime_wasi::ResourceTableError;
Expand Down
193 changes: 6 additions & 187 deletions crates/wasi-http/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,9 @@
//! # Wasmtime's WASI HTTP Implementation
//!
//! This crate is Wasmtime's host implementation of the `wasi:http` package as
//! part of WASIp2. This crate's implementation is primarily built on top of
//! This crate is Wasmtime's host implementation of the `wasi:http` package.
//! This crate's implementation is primarily built on top of
//! [`hyper`] and [`tokio`].
//!
//! # WASI HTTP Interfaces
//!
//! This crate contains implementations of the following interfaces:
//!
//! * [`wasi:http/incoming-handler`]
//! * [`wasi:http/outgoing-handler`]
//! * [`wasi:http/types`]
//!
//! The crate also contains an implementation of the [`wasi:http/proxy`] world.
//!
//! [`wasi:http/proxy`]: crate::bindings::Proxy
//! [`wasi:http/outgoing-handler`]: crate::bindings::http::outgoing_handler::Host
//! [`wasi:http/types`]: crate::bindings::http::types::Host
//! [`wasi:http/incoming-handler`]: crate::bindings::exports::wasi::http::incoming_handler::Guest
//!
//! This crate is very similar to [`wasmtime-wasi`] in the it uses the
//! `bindgen!` macro in Wasmtime to generate bindings to interfaces. Bindings
//! are located in the [`bindings`] module.
//!
//! # The `WasiHttpView` trait
//!
//! All `bindgen!`-generated `Host` traits are implemented in terms of a
Expand Down Expand Up @@ -55,7 +36,7 @@
//! no others. This is useful when working with
//! [`wasmtime_wasi::add_to_linker_async`] for example.
//! * Add individual interfaces such as with the
//! [`bindings::http::outgoing_handler::add_to_linker_get_host`] function.
//! [`p2::bindings::http::outgoing_handler::add_to_linker_get_host`] function.
//! 3. Use [`ProxyPre`](bindings::ProxyPre) to pre-instantiate a component
//! before serving requests.
//! 4. When serving requests use
Expand Down Expand Up @@ -217,15 +198,12 @@
#![expect(clippy::allow_attributes_without_reason, reason = "crate not migrated")]

mod error;
mod http_impl;
mod types_impl;

pub mod body;
pub mod io;
pub mod p2;
pub mod types;

pub mod bindings;

pub use crate::error::{
http_request_error, hyper_request_error, hyper_response_error, HttpError, HttpResult,
};
Expand All @@ -234,70 +212,8 @@ pub use crate::types::{
WasiHttpCtx, WasiHttpImpl, WasiHttpView, DEFAULT_OUTGOING_BODY_BUFFER_CHUNKS,
DEFAULT_OUTGOING_BODY_CHUNK_SIZE,
};
use wasmtime_wasi::IoImpl;
/// Add all of the `wasi:http/proxy` world's interfaces to a [`wasmtime::component::Linker`].
///
/// This function will add the `async` variant of all interfaces into the
/// `Linker` provided. By `async` this means that this function is only
/// compatible with [`Config::async_support(true)`][async]. For embeddings with
/// async support disabled see [`add_to_linker_sync`] instead.
///
/// [async]: wasmtime::Config::async_support
///
/// # Example
///
/// ```
/// use wasmtime::{Engine, Result, Config};
/// use wasmtime::component::{ResourceTable, Linker};
/// use wasmtime_wasi::{IoView, WasiCtx, WasiView};
/// use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView};
///
/// fn main() -> Result<()> {
/// let mut config = Config::new();
/// config.async_support(true);
/// let engine = Engine::new(&config)?;
///
/// let mut linker = Linker::<MyState>::new(&engine);
/// wasmtime_wasi_http::add_to_linker_async(&mut linker)?;
/// // ... add any further functionality to `linker` if desired ...
///
/// Ok(())
/// }
///
/// struct MyState {
/// ctx: WasiCtx,
/// http_ctx: WasiHttpCtx,
/// table: ResourceTable,
/// }
///
/// impl IoView for MyState {
/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// impl WasiHttpView for MyState {
/// fn ctx(&mut self) -> &mut WasiHttpCtx { &mut self.http_ctx }
/// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
/// }
/// ```
pub fn add_to_linker_async<T>(l: &mut wasmtime::component::Linker<T>) -> anyhow::Result<()>
where
T: WasiHttpView + wasmtime_wasi::WasiView,
{
let io_closure = type_annotate_io::<T, _>(|t| wasmtime_wasi::IoImpl(t));
let closure = type_annotate_wasi::<T, _>(|t| wasmtime_wasi::WasiImpl(wasmtime_wasi::IoImpl(t)));
wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::io::poll::add_to_linker_get_host(l, io_closure)?;
wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, io_closure)?;
wasmtime_wasi::bindings::io::streams::add_to_linker_get_host(l, io_closure)?;
wasmtime_wasi::bindings::cli::stdin::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::cli::stdout::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::cli::stderr::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::random::random::add_to_linker_get_host(l, closure)?;

add_only_http_to_linker_async(l)
}
#[doc(inline)]
pub use p2::*;

// NB: workaround some rustc inference - a future refactoring may make this
// obsolete.
Expand All @@ -319,100 +235,3 @@ where
{
val
}

/// A slimmed down version of [`add_to_linker_async`] which only adds
/// `wasi:http` interfaces to the linker.
///
/// This is useful when using [`wasmtime_wasi::add_to_linker_async`] for
/// example to avoid re-adding the same interfaces twice.
pub fn add_only_http_to_linker_async<T>(
l: &mut wasmtime::component::Linker<T>,
) -> anyhow::Result<()>
where
T: WasiHttpView,
{
let closure = type_annotate_http::<T, _>(|t| WasiHttpImpl(IoImpl(t)));
crate::bindings::http::outgoing_handler::add_to_linker_get_host(l, closure)?;
crate::bindings::http::types::add_to_linker_get_host(l, closure)?;

Ok(())
}

/// Add all of the `wasi:http/proxy` world's interfaces to a [`wasmtime::component::Linker`].
///
/// This function will add the `sync` variant of all interfaces into the
/// `Linker` provided. For embeddings with async support see
/// [`add_to_linker_async`] instead.
///
/// # Example
///
/// ```
/// use wasmtime::{Engine, Result, Config};
/// use wasmtime::component::{ResourceTable, Linker};
/// use wasmtime_wasi::{IoView, WasiCtx, WasiView};
/// use wasmtime_wasi_http::{WasiHttpCtx, WasiHttpView};
///
/// fn main() -> Result<()> {
/// let config = Config::default();
/// let engine = Engine::new(&config)?;
///
/// let mut linker = Linker::<MyState>::new(&engine);
/// wasmtime_wasi_http::add_to_linker_sync(&mut linker)?;
/// // ... add any further functionality to `linker` if desired ...
///
/// Ok(())
/// }
///
/// struct MyState {
/// ctx: WasiCtx,
/// http_ctx: WasiHttpCtx,
/// table: ResourceTable,
/// }
/// impl IoView for MyState {
/// fn table(&mut self) -> &mut ResourceTable { &mut self.table }
/// }
/// impl WasiHttpView for MyState {
/// fn ctx(&mut self) -> &mut WasiHttpCtx { &mut self.http_ctx }
/// }
/// impl WasiView for MyState {
/// fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx }
/// }
/// ```
pub fn add_to_linker_sync<T>(l: &mut wasmtime::component::Linker<T>) -> anyhow::Result<()>
where
T: WasiHttpView + wasmtime_wasi::WasiView,
{
let io_closure = type_annotate_io::<T, _>(|t| wasmtime_wasi::IoImpl(t));
let closure = type_annotate_wasi::<T, _>(|t| wasmtime_wasi::WasiImpl(wasmtime_wasi::IoImpl(t)));

wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::sync::io::poll::add_to_linker_get_host(l, io_closure)?;
wasmtime_wasi::bindings::sync::io::streams::add_to_linker_get_host(l, io_closure)?;
wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, io_closure)?;
wasmtime_wasi::bindings::cli::stdin::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::cli::stdout::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::cli::stderr::add_to_linker_get_host(l, closure)?;
wasmtime_wasi::bindings::random::random::add_to_linker_get_host(l, closure)?;

add_only_http_to_linker_sync(l)?;

Ok(())
}

/// A slimmed down version of [`add_to_linker_sync`] which only adds
/// `wasi:http` interfaces to the linker.
///
/// This is useful when using [`wasmtime_wasi::add_to_linker_sync`] for
/// example to avoid re-adding the same interfaces twice.
pub fn add_only_http_to_linker_sync<T>(l: &mut wasmtime::component::Linker<T>) -> anyhow::Result<()>
where
T: WasiHttpView,
{
let closure = type_annotate_http::<T, _>(|t| WasiHttpImpl(IoImpl(t)));

crate::bindings::http::outgoing_handler::add_to_linker_get_host(l, closure)?;
crate::bindings::http::types::add_to_linker_get_host(l, closure)?;

Ok(())
}
Loading

0 comments on commit 815b81a

Please sign in to comment.