From 569287b15b6482a39f2c816f103574c3b35351f8 Mon Sep 17 00:00:00 2001 From: Marcos Casagrande Date: Tue, 4 Oct 2022 15:48:50 +0200 Subject: perf(ext/fetch): consume body using ops (#16038) This commit adds a fast path to `Request` and `Response` that make consuming request bodies much faster when using `Body#text`, `Body#arrayBuffer`, and `Body#blob`, if the body is a FastStream. Because the response bodies for `fetch` are FastStream, this speeds up consuming `fetch` response bodies significantly. --- core/ops_builtin.rs | 21 +++++++++++++++++++++ core/resources.rs | 4 ++++ 2 files changed, 25 insertions(+) (limited to 'core') diff --git a/core/ops_builtin.rs b/core/ops_builtin.rs index 6ca2a132c..7393d4b69 100644 --- a/core/ops_builtin.rs +++ b/core/ops_builtin.rs @@ -34,6 +34,7 @@ pub(crate) fn init_builtins() -> Extension { op_add::decl(), // // TODO(@AaronO): track IO metrics for builtin streams op_read::decl(), + op_read_all::decl(), op_write::decl(), op_shutdown::decl(), op_metrics::decl(), @@ -168,6 +169,26 @@ async fn op_read( resource.read_return(buf).await.map(|(n, _)| n as u32) } +#[op] +async fn op_read_all( + state: Rc>, + rid: ResourceId, +) -> Result { + let resource = state.borrow().resource_table.get_any(rid)?; + let (min, maximum) = resource.size_hint(); + let size = maximum.unwrap_or(min) as usize; + + let mut buffer = Vec::with_capacity(size); + loop { + let tmp = ZeroCopyBuf::new_temp(vec![0u8; 64 * 1024]); + let (nread, tmp) = resource.clone().read_return(tmp).await?; + if nread == 0 { + return Ok(buffer.into()); + } + buffer.extend_from_slice(&tmp[..nread]); + } +} + #[op] async fn op_write( state: Rc>, diff --git a/core/resources.rs b/core/resources.rs index 56c9298af..1a1ba3193 100644 --- a/core/resources.rs +++ b/core/resources.rs @@ -64,6 +64,10 @@ pub trait Resource: Any + 'static { fn backing_fd(self: Rc) -> Option { None } + + fn size_hint(&self) -> (u64, Option) { + (0, None) + } } impl dyn Resource { -- cgit v1.2.3