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

fix(server): Fix race condition in client dispatcher (#2419) #3041

Merged
merged 1 commit into from
Nov 7, 2022

Conversation

jfourie1
Copy link
Contributor

@jfourie1 jfourie1 commented Nov 2, 2022

There exists a race condition in ClientTask::poll() when the request that is sent via h2::client::send_request() is pending open. A task will be spawned to wait for send capacity on the sendstream. Because this same stream is also stored in the pending member of h2::client::SendRequest the next iteration of the poll() loop can call poll_ready() and call wait_send() on the same stream passed into the spawned task.

Fix this by always calling poll_ready() after send_request(). If this call to poll_ready() returns Pending save the necessary context in ClientTask and only spawn the task that will eventually resolve to the response after poll_ready() returns Ok.

There exists a race condition in ClientTask::poll() when the request
that is sent via h2::client::send_request() is pending open. A task will
be spawned to wait for send capacity on the sendstream. Because this
same stream is also stored in the pending member of
h2::client::SendRequest the next iteration of the poll() loop can call
poll_ready() and call wait_send() on the same stream passed into the
spawned task.

Fix this by always calling poll_ready() after send_request(). If this
call to poll_ready() returns Pending save the necessary context in
ClientTask and only spawn the task that will eventually resolve to the
response after poll_ready() returns Ok.
@jeromegn
Copy link

jeromegn commented Nov 3, 2022

Worth mentioning this fixes the reproduction:

2022-11-03T18:48:08.374569Z  INFO h2_repro: 100 requests on 50 streams
2022-11-03T18:48:08.374591Z  INFO h2_repro: (Set $H2_REQUESTS and $H2_MAX_STREAMS environment variables to adjust)
2022-11-03T18:48:08.407164Z  INFO h2_repro: H1: Completed 100 / 100
2022-11-03T18:48:08.425192Z  INFO h2_repro: H2: Completed 100 / 100

Copy link
Member

@seanmonstar seanmonstar left a comment

Choose a reason for hiding this comment

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

Phenomenal work debugging this issue!!!

@seanmonstar seanmonstar merged commit 2f1c0b7 into hyperium:0.14.x Nov 7, 2022
seanmonstar pushed a commit that referenced this pull request Nov 7, 2022
There exists a race condition in ClientTask::poll() when the request
that is sent via h2::client::send_request() is pending open. A task will
be spawned to wait for send capacity on the sendstream. Because this
same stream is also stored in the pending member of
h2::client::SendRequest the next iteration of the poll() loop can call
poll_ready() and call wait_send() on the same stream passed into the
spawned task.

Fix this by always calling poll_ready() after send_request(). If this
call to poll_ready() returns Pending save the necessary context in
ClientTask and only spawn the task that will eventually resolve to the
response after poll_ready() returns Ok.
seanmonstar pushed a commit that referenced this pull request Nov 7, 2022
There exists a race condition in ClientTask::poll() when the request
that is sent via h2::client::send_request() is pending open. A task will
be spawned to wait for send capacity on the sendstream. Because this
same stream is also stored in the pending member of
h2::client::SendRequest the next iteration of the poll() loop can call
poll_ready() and call wait_send() on the same stream passed into the
spawned task.

Fix this by always calling poll_ready() after send_request(). If this
call to poll_ready() returns Pending save the necessary context in
ClientTask and only spawn the task that will eventually resolve to the
response after poll_ready() returns Ok.
seanmonstar pushed a commit that referenced this pull request Nov 7, 2022
There exists a race condition in ClientTask::poll() when the request
that is sent via h2::client::send_request() is pending open. A task will
be spawned to wait for send capacity on the sendstream. Because this
same stream is also stored in the pending member of
h2::client::SendRequest the next iteration of the poll() loop can call
poll_ready() and call wait_send() on the same stream passed into the
spawned task.

Fix this by always calling poll_ready() after send_request(). If this
call to poll_ready() returns Pending save the necessary context in
ClientTask and only spawn the task that will eventually resolve to the
response after poll_ready() returns Ok.
bors bot referenced this pull request in OpenPoolProject/stratum Dec 2, 2022
329: fix(deps): update rust crate hyper to 0.14.23 r=renovate[bot] a=renovate[bot]

[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [hyper](https://hyper.rs) ([source](https://github.com/hyperium/hyper)) | dependencies | patch | `0.14.20` -> `0.14.23` |

---

### Release Notes

<details>
<summary>hyperium/hyper</summary>

### [`v0.14.23`](https://github.com/hyperium/hyper/releases/tag/v0.14.23)

[Compare Source](https://github.com/hyperium/hyper/compare/v0.14.22...v0.14.23)

#### Bug Fixes

-   **http2:** Fix race condition in client dispatcher ([#&#8203;3041](https://github.com/hyperium/hyper/issues/3041)) ([2f1c0b72](https://github.com/hyperium/hyper/commit/2f1c0b720da4553fff216a38018a78ecafe23d60), closes [#&#8203;2419](https://github.com/hyperium/hyper/issues/2419))
-   **dependencies**: Really fix compile-time feature for `socket2` dependency.

#### New Contributors

-   [`@&#8203;jfourie1](https://github.com/jfourie1)` made their first contribution in [https://github.com/hyperium/hyper/pull/3041](https://github.com/hyperium/hyper/pull/3041)

### [`v0.14.22`](https://github.com/hyperium/hyper/releases/tag/v0.14.22)

[Compare Source](https://github.com/hyperium/hyper/compare/v0.14.21...v0.14.22)

#### Bug Fixes

-   **server:** fix compile-time cfgs for TCP keepalive options ([#&#8203;3039](https://github.com/hyperium/hyper/issues/3039)) ([e8765e0f](https://github.com/hyperium/hyper/commit/e8765e0febd0267472799dcd1109af75944c2637), closes [#&#8203;3038](https://github.com/hyperium/hyper/issues/3038))

### [`v0.14.21`](https://github.com/hyperium/hyper/releases/tag/v0.14.21)

[Compare Source](https://github.com/hyperium/hyper/compare/v0.14.20...v0.14.21)

#### Bug Fixes

-   **client:** send an error back to client when dispatch misbehaves () ([9fa36382](https://github.com/hyperium/hyper/commit/9fa363829ced232acb18c31ebab8ffb93f691ecc), closes [#&#8203;2649](https://github.com/hyperium/hyper/issues/2649))
-   **http1:** fix `http1_header_read_timeout` to use same future ([#&#8203;2891](https://github.com/hyperium/hyper/issues/2891)) ([c5a14e7c](https://github.com/hyperium/hyper/commit/c5a14e7c087424001223aaeb2dad532ba4ee6063))

#### Features

-   **http1:** allow ignoring invalid header lines in requests ([73dd4746](https://github.com/hyperium/hyper/commit/73dd474652f5e71fe8a87baa6f9b2490ae746eb3))
-   **server:** add `Server::tcp_keepalive_interval` and `Server::tcp_keepalive_retries` ([#&#8203;2991](https://github.com/hyperium/hyper/issues/2991)) ([287d7124](https://github.com/hyperium/hyper/commit/287d712483aec6671427438d60ed2a72f856fd9f))

#### New Contributors

-   [`@&#8203;hansonchar](https://github.com/hansonchar)` made their first contribution in [https://github.com/hyperium/hyper/pull/2991](https://github.com/hyperium/hyper/pull/2991)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/OpenPoolProject/stratum).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC40NC4wIiwidXBkYXRlZEluVmVyIjoiMzQuNDQuMCJ9-->


Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
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.

3 participants