Skip to content

Commit

Permalink
wasi-http: make the buffer and budget capacity of the OutgoingBody wr…
Browse files Browse the repository at this point in the history
…iter configurable
  • Loading branch information
iawia002 committed Nov 25, 2024
1 parent 6767488 commit ab6e216
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use std::io::{self, Read};
use test_programs::wasi::http::types::{Method, Scheme};

fn main() {
// TODO: ensure more than 700 bytes is allowed without error
const LEN: usize = 700;
const LEN: usize = 5000;
let mut buffer = [0; LEN];
let addr = std::env::var("HTTP_SERVER").unwrap();
io::repeat(0b001).read_exact(&mut buffer).unwrap();
Expand Down
12 changes: 8 additions & 4 deletions crates/wasi-http/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,12 @@ pub struct HostOutgoingBody {

impl HostOutgoingBody {
/// Create a new `HostOutgoingBody`
pub fn new(context: StreamContext, size: Option<u64>) -> (Self, HyperOutgoingBody) {
pub fn new(
context: StreamContext,
size: Option<u64>,
writer_buffer: usize,
write_budget: usize,
) -> (Self, HyperOutgoingBody) {
let written = size.map(WrittenState::new);

use tokio::sync::oneshot::error::RecvError;
Expand Down Expand Up @@ -469,17 +474,16 @@ impl HostOutgoingBody {
}
}

let (body_sender, body_receiver) = mpsc::channel(2);
let (body_sender, body_receiver) = mpsc::channel(writer_buffer);
let (finish_sender, finish_receiver) = oneshot::channel();
let body_impl = BodyImpl {
body_receiver,
finish_receiver: Some(finish_receiver),
}
.boxed();

// TODO: this capacity constant is arbitrary, and should be configurable
let output_stream =
BodyWriteStream::new(context, 1024 * 1024, body_sender, written.clone());
BodyWriteStream::new(context, write_budget, body_sender, written.clone());

(
Self {
Expand Down
38 changes: 38 additions & 0 deletions crates/wasi-http/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,20 @@ pub trait WasiHttpView: Send {
fn is_forbidden_header(&mut self, _name: &HeaderName) -> bool {
false
}

/// Specify the buffer capacity for the body writer.
/// A larger buffer capacity allows for more frequent data writes, which may
/// correspondingly increase memory usage. The buffer value must be at least 2.
/// Default: 2.
fn writer_buffer(&mut self) -> usize {
2
}

/// Specify the budget capacity for the body writer.
/// Default: 1024 * 1024.
fn write_budget(&mut self) -> usize {
1024 * 1024
}
}

impl<T: ?Sized + WasiHttpView> WasiHttpView for &mut T {
Expand Down Expand Up @@ -156,6 +170,14 @@ impl<T: ?Sized + WasiHttpView> WasiHttpView for &mut T {
fn is_forbidden_header(&mut self, name: &HeaderName) -> bool {
T::is_forbidden_header(self, name)
}

fn writer_buffer(&mut self) -> usize {
T::writer_buffer(self)
}

fn write_budget(&mut self) -> usize {
T::write_budget(self)
}
}

impl<T: ?Sized + WasiHttpView> WasiHttpView for Box<T> {
Expand Down Expand Up @@ -187,6 +209,14 @@ impl<T: ?Sized + WasiHttpView> WasiHttpView for Box<T> {
fn is_forbidden_header(&mut self, name: &HeaderName) -> bool {
T::is_forbidden_header(self, name)
}

fn writer_buffer(&mut self) -> usize {
T::writer_buffer(self)
}

fn write_budget(&mut self) -> usize {
T::write_budget(self)
}
}

/// A concrete structure that all generated `Host` traits are implemented for.
Expand Down Expand Up @@ -233,6 +263,14 @@ impl<T: WasiHttpView> WasiHttpView for WasiHttpImpl<T> {
fn is_forbidden_header(&mut self, name: &HeaderName) -> bool {
self.0.is_forbidden_header(name)
}

fn writer_buffer(&mut self) -> usize {
self.0.writer_buffer()
}

fn write_budget(&mut self) -> usize {
self.0.write_budget()
}
}

/// Returns `true` when the header is forbidden according to this [`WasiHttpView`] implementation.
Expand Down
10 changes: 8 additions & 2 deletions crates/wasi-http/src/types_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,8 @@ where
&mut self,
request: Resource<HostOutgoingRequest>,
) -> wasmtime::Result<Result<Resource<HostOutgoingBody>, ()>> {
let writer_buffer = self.writer_buffer();
let write_budget = self.write_budget();
let req = self
.table()
.get_mut(&request)
Expand All @@ -405,7 +407,8 @@ where
Err(e) => return Ok(Err(e)),
};

let (host_body, hyper_body) = HostOutgoingBody::new(StreamContext::Request, size);
let (host_body, hyper_body) =
HostOutgoingBody::new(StreamContext::Request, size, writer_buffer, write_budget);

req.body = Some(hyper_body);

Expand Down Expand Up @@ -751,6 +754,8 @@ where
&mut self,
id: Resource<HostOutgoingResponse>,
) -> wasmtime::Result<Result<Resource<HostOutgoingBody>, ()>> {
let writer_buffer = self.writer_buffer();
let write_budget = self.write_budget();
let resp = self.table().get_mut(&id)?;

if resp.body.is_some() {
Expand All @@ -762,7 +767,8 @@ where
Err(e) => return Ok(Err(e)),
};

let (host, body) = HostOutgoingBody::new(StreamContext::Response, size);
let (host, body) =
HostOutgoingBody::new(StreamContext::Response, size, writer_buffer, write_budget);

resp.body.replace(body);

Expand Down
8 changes: 8 additions & 0 deletions crates/wasi-http/tests/all/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ impl WasiHttpView for Ctx {
fn is_forbidden_header(&mut self, name: &hyper::header::HeaderName) -> bool {
name.as_str() == "custom-forbidden-header"
}

fn writer_buffer(&mut self) -> usize {
10
}

fn write_budget(&mut self) -> usize {
4096
}
}

fn store(engine: &Engine, server: &Server) -> Store<Ctx> {
Expand Down

0 comments on commit ab6e216

Please sign in to comment.