-
Notifications
You must be signed in to change notification settings - Fork 5.2k
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
refactor(ext/http): rewrite hyper integration and fix bug #12332
Conversation
9c01b43
to
71b312a
Compare
89be132
to
9d94ef2
Compare
This avoids a bunch of duplicated code.
a2dad15
to
8589f97
Compare
This avoids a bunch of duplicated code.
64dbbae
to
343ba0d
Compare
This avoids a bunch of duplicated code.
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.
Took a first look at this, and it is looking very good. The code is very readable, and a lot less prone to poll-after-ready issues. Have you done benchmarks yet?
ext/http/lib.rs
Outdated
("op_http_response_close", op_async(op_http_response_close)), | ||
("op_http_accept", op_async(op_http_accept)), | ||
("op_http_read", op_async(op_http_read)), | ||
("op_http_write_response", op_async(op_http_write_response)), |
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.
Might make sense to call this op_http_respond
instead of op_http_write_response
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.
I think op_http_write_headers
makes more sense actually.
(I know it also can write the body, but I see that as a performance hack, not a clean abstraction).
method, | ||
headersList, | ||
url, | ||
] = nextRequest; | ||
SetPrototypeAdd(this.managedResources, streamRid); |
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 seems there is only one resource placed into managedResources now. Can managedResources be removed entirely?
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.
The managedResources
set is associated with an HttpConn instance. It contains multiple HttpStreamResource
s.
@@ -29,7 +30,7 @@ fn op_http_start( | |||
let (read_half, write_half) = resource.into_inner(); | |||
let tcp_stream = read_half.reunite(write_half)?; | |||
let addr = tcp_stream.local_addr()?; | |||
return deno_http::start_http(state, tcp_stream, addr, "http"); | |||
return http_create_conn_resource(state, tcp_stream, addr, "http"); | |||
} |
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.
Not actionable for this PR, just an observation:
The runtime/ops/http.rs
module seems useless. Why aren't these ops just in the ext/http/
?
@@ -587,6 +585,5 @@ pub fn run_web_worker( | |||
debug!("Worker thread shuts down {}", &name); | |||
result | |||
}; | |||
|
|||
rt.block_on(fut) | |||
run_basic(fut) |
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.
unrelated changes?
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.
Necessary, but in a separate commit.
let (request_tx, request_rx) = oneshot::channel(); | ||
let (response_tx, response_rx) = oneshot::channel(); |
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.
I would guess the use of channels here is why the refactor is 10% slower.
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.
I don't think so.
// A local task that polls the hyper connection future to completion. | ||
let task_fut = async move { | ||
pin_mut!(shutdown_fut); | ||
pin_mut!(conn_fut); | ||
let result = match select(conn_fut, shutdown_fut).await { | ||
Either::Left((result, _)) => result, | ||
Either::Right((_, mut conn_fut)) => { | ||
conn_fut.as_mut().graceful_shutdown(); | ||
conn_fut.await | ||
} | ||
}; | ||
filter_enotconn(result).map_err(Arc::from) | ||
}; | ||
let (task_fut, closed_fut) = task_fut.remote_handle(); | ||
let closed_fut = closed_fut.shared(); | ||
spawn_local(task_fut); |
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.
Very fancy, but apparently working.
Hopefully this organization will allow us to experiment with running the hyper server on a separate thread more easily.
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.
Very fancy, but apparently working.
What would you suggest that's less fancy?
This avoids a bunch of duplicated code.
This avoids a bunch of duplicated code.
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
- Combining the resources is a big clean up
- The rust side of the code is much easier to reason about.
- This also fixes a bug
However this patch also degrades throughput performance by about 4% on hello-world server. I've done another perf analysis below. We think the benefits of this refactor outweigh the slowness. We hope this serves as good foundation for further improvements in ext/http
.
Performance Analysis 2
Using: ./target/release/deno run --allow-net cli/bench/deno_http_native.js
and wrk --latency -d 20s http:https://127.0.0.1:4500
Summary: throughput degraded by 4%, latency seems to be marginally better.
Deno v1.15.3
Running 20s test @ http:https://127.0.0.1:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 99.53us 99.42us 7.86ms 99.30%
Req/Sec 48.21k 1.69k 50.66k 99.00%
Latency Distribution
50% 94.00us
75% 112.00us
90% 135.00us
99% 186.00us
1928035 requests in 20.10s, 159.97MB read
Requests/sec: 95922.25
Transfer/sec: 7.96MB
Running 20s test @ http:https://127.0.0.1:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 98.50us 37.24us 3.58ms 82.77%
Req/Sec 47.92k 1.61k 49.61k 99.00%
Latency Distribution
50% 95.00us
75% 113.00us
90% 136.00us
99% 187.00us
1916882 requests in 20.10s, 159.04MB read
Requests/sec: 95370.21
Transfer/sec: 7.91MB
This Patch
(version bb64927)
Running 20s test @ http:https://127.0.0.1:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 101.77us 32.60us 3.81ms 83.89%
Req/Sec 46.00k 1.40k 47.69k 98.01%
Latency Distribution
50% 100.00us
75% 115.00us
90% 131.00us
99% 167.00us
1840014 requests in 20.10s, 152.67MB read
Requests/sec: 91543.34
Transfer/sec: 7.60MB
Running 20s test @ http:https://127.0.0.1:4500
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 101.91us 29.00us 3.19ms 79.30%
Req/Sec 45.90k 1.40k 47.43k 98.26%
Latency Distribution
50% 101.00us
75% 115.00us
90% 132.00us
99% 167.00us
1835615 requests in 20.10s, 152.30MB read
Requests/sec: 91323.73
Transfer/sec: 7.58MB
Node v17.0.1 baseline
Running 20s test @ http:https://127.0.0.1:4544
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 100.67us 171.98us 12.41ms 99.67%
Req/Sec 50.30k 2.86k 53.15k 98.01%
Latency Distribution
50% 89.00us
75% 115.00us
90% 150.00us
99% 209.00us
2011687 requests in 20.10s, 257.08MB read
Requests/sec: 100084.42
Transfer/sec: 12.79MB
Running 20s test @ http:https://127.0.0.1:4544
2 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 98.57us 114.68us 9.48ms 99.17%
Req/Sec 50.33k 2.81k 52.86k 97.76%
Latency Distribution
50% 89.00us
75% 115.00us
90% 150.00us
99% 208.00us
2012718 requests in 20.10s, 257.21MB read
Requests/sec: 100134.06
Transfer/sec: 12.80MB
This avoids a bunch of duplicated code.
…noland#12332)" This reverts commit 5b1e537.
No description provided.