-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf(ext/fetch): consume body using ops #16038
Changes from 6 commits
3e07a56
60055f8
e4ff608
3723ece
4f088af
7bd3277
dc777d4
91ac250
c2954d0
bca8d96
922dd93
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. | ||
|
||
const addr = Deno.args[0] || "127.0.0.1:4500"; | ||
const [hostname, port] = addr.split(":"); | ||
const { serve } = Deno; | ||
|
||
async function handler(request) { | ||
try { | ||
const buffer = await request.arrayBuffer(); | ||
return new Response(buffer.byteLength); | ||
} catch (e) { | ||
console.log(e); | ||
} | ||
} | ||
|
||
serve(handler, { hostname, port }); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
wrk.method = "POST" | ||
wrk.headers["Content-Type"] = "application/octet-stream" | ||
|
||
file = io.open("./cli/bench/testdata/128k.bin", "rb") | ||
wrk.body = file:read("*a") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. | ||
|
||
const addr = Deno.args[0] || "127.0.0.1:4500"; | ||
const [hostname, port] = addr.split(":"); | ||
const listener = Deno.listen({ hostname, port: Number(port) }); | ||
console.log("Server listening on", addr); | ||
|
||
for await (const conn of listener) { | ||
(async () => { | ||
const requests = Deno.serveHttp(conn); | ||
for await (const { respondWith, request } of requests) { | ||
if (request.method == "POST") { | ||
const buffer = await request.arrayBuffer(); | ||
respondWith(new Response(buffer.byteLength)) | ||
.catch((e) => console.log(e)); | ||
} | ||
} | ||
})(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
wrk.method = "POST" | ||
wrk.headers["Content-Type"] = "application/octet-stream" | ||
|
||
file = io.open("./cli/bench/testdata/128k.bin", "rb") | ||
wrk.body = file:read("*a") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. | ||
const http = require("http"); | ||
const port = process.argv[2] || "4544"; | ||
console.log("port", port); | ||
http | ||
.Server((req, res) => { | ||
if (req.method == "POST") { | ||
let chunks = []; | ||
req.on("data", function (data) { | ||
chunks.push(data); | ||
}); | ||
req.on("end", function () { | ||
const buffer = Buffer.concat(chunks); | ||
res.end(buffer.byteLength.toString()); | ||
}); | ||
} | ||
}) | ||
.listen(port); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
wrk.method = "POST" | ||
wrk.headers["Content-Type"] = "application/octet-stream" | ||
|
||
file = io.open("./cli/bench/testdata/128k.bin", "rb") | ||
wrk.body = file:read("*a") |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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<RefCell<OpState>>, | ||
rid: ResourceId, | ||
) -> Result<ZeroCopyBuf, Error> { | ||
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]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I presume the tmp could be moved out of the loop and only allocated once? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
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<RefCell<OpState>>, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. #16115 will allow us to get rid of multiple allocations in this op in a follow up.