Skip to content
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

Merged
merged 4 commits into from
Nov 8, 2021

Conversation

piscisaureus
Copy link
Member

@piscisaureus piscisaureus commented Oct 5, 2021

No description provided.

@CLAassistant
Copy link

CLAassistant commented Oct 15, 2021

CLA assistant check
All committers have signed the CLA.

piscisaureus added a commit to piscisaureus/deno that referenced this pull request Oct 21, 2021
This avoids a bunch of duplicated code.
piscisaureus added a commit to piscisaureus/deno that referenced this pull request Oct 23, 2021
This avoids a bunch of duplicated code.
piscisaureus added a commit to piscisaureus/deno that referenced this pull request Oct 26, 2021
This avoids a bunch of duplicated code.
Copy link
Member

@lucacasonato lucacasonato left a 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)),
Copy link
Contributor

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

Copy link
Member Author

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);
Copy link
Member

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?

Copy link
Member Author

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 HttpStreamResources.

@@ -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");
}
Copy link
Member

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated changes?

Copy link
Member Author

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.

Comment on lines +144 to +145
let (request_tx, request_rx) = oneshot::channel();
let (response_tx, response_rx) = oneshot::channel();
Copy link
Member

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.

Copy link
Member Author

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.

Comment on lines +113 to +128
// 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);
Copy link
Member

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.

Copy link
Member Author

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?

ext/http/lib.rs Outdated Show resolved Hide resolved
ext/http/lib.rs Show resolved Hide resolved
piscisaureus added a commit to piscisaureus/deno that referenced this pull request Nov 5, 2021
piscisaureus added a commit to piscisaureus/deno that referenced this pull request Nov 5, 2021
piscisaureus added a commit to piscisaureus/deno that referenced this pull request Nov 5, 2021
This avoids a bunch of duplicated code.
piscisaureus added a commit to piscisaureus/deno that referenced this pull request Nov 5, 2021
piscisaureus added a commit to piscisaureus/deno that referenced this pull request Nov 5, 2021
piscisaureus added a commit to piscisaureus/deno that referenced this pull request Nov 5, 2021
piscisaureus added a commit to piscisaureus/deno that referenced this pull request Nov 5, 2021
This avoids a bunch of duplicated code.
piscisaureus added a commit to piscisaureus/deno that referenced this pull request Nov 5, 2021
Copy link
Member

@ry ry left a 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Multiple overlapping HttpConn#nextRequest() promises are lost in space
5 participants