-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
feat(ext/web): resourceForReadableStream #20180
Conversation
|
||
type SenderCell = RefCell<Option<Sender<Result<BufView, Error>>>>; | ||
|
||
// This indirection allows us to more easily integrate the fast streams work at a later date |
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.
A large amount of this code will migrate to deno_core once #20080 fully lands.
0877136
to
4409297
Compare
@@ -141,8 141,7 @@ Deno.test("[node/http] chunked response", async () => { | |||
} | |||
}); | |||
|
|||
// TODO(kt3k): This test case exercises the workaround for https://github.com/denoland/deno/issues/17194 | |||
// This should be removed when #17194 is resolved. | |||
// Test empty chunks: https://github.com/denoland/deno/issues/17194 |
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.
This test caught a legit bug, so I am removing the TODO as it's worth keeping.
await listeningPromise; | ||
const resp = await fetch(`http://127.0.0.1:${servePort}/`); | ||
const text = await resp.text(); | ||
try { |
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.
HTTP behaves more like you would expect now -- it will always return EOF if there is an error in the middle of a stream (matching the behaviour if there was an error in any other resource).
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 tests!
return stream; | ||
} | ||
|
||
async function asyncResponse(responseBodies, req, status, stream) { |
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.
Wow, that simplifies a lot
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.
It does quite a bit. This probably opens up optimization opportunities for V8.
I think it will simplify the fetch code quite a bit as well.
|
||
#[op2(fast)] | ||
#[smi] | ||
pub fn op_readable_stream_resource_close(sender: *const c_void) { |
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.
How is it different that a regular close? Could it be done in Resource::close
instead?
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.
As there are two ends to the internal "pipe", we need to be able to close them both independently. The close method on the resource propagates to this inner side through the completion handle.
Effectively this allows both sides to have independent lifetimes (though shutting down one side will shut the other down indirectly).
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.
LGTM
Extracted from fast streams work. This is a resource wrapper for `ReadableStream`, allowing us to treat all `ReadableStream` instances as resources, and remove special paths in both `fetch` and `serve`. Performance with a ReadableStream response yields ~18% improvement: ``` return new Response(new ReadableStream({ start(controller) { controller.enqueue(new Uint8Array([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100])); controller.close(); } }) ``` This patch: ``` 12:36 $ third_party/prebuilt/mac/wrk http://localhost:8080 Running 10s test @ http://localhost:8080 2 threads and 10 connections Thread Stats Avg Stdev Max /- Stdev Latency 99.96us 100.03us 6.65ms 98.84% Req/Sec 47.73k 2.43k 51.02k 89.11% 959308 requests in 10.10s, 117.10MB read Requests/sec: 94978.71 Transfer/sec: 11.59MB ``` main: ``` Running 10s test @ http://localhost:8080 2 threads and 10 connections Thread Stats Avg Stdev Max /- Stdev Latency 163.03us 685.51us 19.73ms 99.27% Req/Sec 39.50k 3.98k 66.11k 95.52% 789582 requests in 10.10s, 82.83MB read Requests/sec: 78182.65 Transfer/sec: 8.20MB ```
Extracted from fast streams work. This is a resource wrapper for `ReadableStream`, allowing us to treat all `ReadableStream` instances as resources, and remove special paths in both `fetch` and `serve`. Performance with a ReadableStream response yields ~18% improvement: ``` return new Response(new ReadableStream({ start(controller) { controller.enqueue(new Uint8Array([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100])); controller.close(); } }) ``` This patch: ``` 12:36 $ third_party/prebuilt/mac/wrk http://localhost:8080 Running 10s test @ http://localhost:8080 2 threads and 10 connections Thread Stats Avg Stdev Max /- Stdev Latency 99.96us 100.03us 6.65ms 98.84% Req/Sec 47.73k 2.43k 51.02k 89.11% 959308 requests in 10.10s, 117.10MB read Requests/sec: 94978.71 Transfer/sec: 11.59MB ``` main: ``` Running 10s test @ http://localhost:8080 2 threads and 10 connections Thread Stats Avg Stdev Max /- Stdev Latency 163.03us 685.51us 19.73ms 99.27% Req/Sec 39.50k 3.98k 66.11k 95.52% 789582 requests in 10.10s, 82.83MB read Requests/sec: 78182.65 Transfer/sec: 8.20MB ```
Extracted from fast streams work.
This is a resource wrapper for
ReadableStream
, allowing us to treat allReadableStream
instances as resources, and remove special paths in bothfetch
andserve
.Performance with a ReadableStream response yields ~18% improvement:
This patch:
main: