Skip to content

Fix leaked HTTP response sent after close#105293

Merged
elasticsearchmachine merged 4 commits intoelastic:mainfrom
DaveCTurner:2024/02/08/http-response-after-close
Feb 8, 2024
Merged

Fix leaked HTTP response sent after close#105293
elasticsearchmachine merged 4 commits intoelastic:mainfrom
DaveCTurner:2024/02/08/http-response-after-close

Conversation

@DaveCTurner
Copy link
Copy Markdown
Member

Today a HttpResponse is always released via a ChannelPromise which
means the release happens on a network thread. However, it's possible we
try and send a HttpResponse after the node has got far enough through
shutdown that it doesn't have any running network threads left, which
means the response just leaks.

This is no big deal in production, it becomes irrelevant when the
process exits, but in tests we start and stop many nodes within the same
process so mustn't leak anything.

At this point in shutdown, all HTTP channels are now closed, so it's
sufficient to check whether the channel is open first, and to fail the
listener on the calling thread if not. That's what this commit does.

Closes #104651

Today a `HttpResponse` is always released via a `ChannelPromise` which
means the release happens on a network thread. However, it's possible we
try and send a `HttpResponse` after the node has got far enough through
shutdown that it doesn't have any running network threads left, which
means the response just leaks.

This is no big deal in production, it becomes irrelevant when the
process exits, but in tests we start and stop many nodes within the same
process so mustn't leak anything.

At this point in shutdown, all HTTP channels are now closed, so it's
sufficient to check whether the channel is open first, and to fail the
listener on the calling thread if not. That's what this commit does.

Closes elastic#104651
@DaveCTurner DaveCTurner added >bug :Distributed/Network Http and internode communication implementations v8.13.0 v8.12.2 labels Feb 8, 2024
@elasticsearchmachine elasticsearchmachine added the Team:Distributed Meta label for distributed team. label Feb 8, 2024
@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

Hi @DaveCTurner, I've created a changelog YAML for you.

@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-distributed (Team:Distributed)

try (var client = RestClient.builder(new HttpHost(address.getAddress(), address.getPort())).build()) {
client.performRequestAsync(new Request("GET", url), ActionTestUtils.wrapAsRestResponseListener(ActionListener.noop()));
safeAwait(handlingRequestLatch);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Tiny nit: it's probably on purpose, but that empty line seems unnecessary!

@DaveCTurner DaveCTurner added auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) auto-backport-and-merge labels Feb 8, 2024
@elasticsearchmachine elasticsearchmachine merged commit 97dbb2a into elastic:main Feb 8, 2024
DaveCTurner added a commit to DaveCTurner/elasticsearch that referenced this pull request Feb 8, 2024
Today a `HttpResponse` is always released via a `ChannelPromise` which
means the release happens on a network thread. However, it's possible we
try and send a `HttpResponse` after the node has got far enough through
shutdown that it doesn't have any running network threads left, which
means the response just leaks.

This is no big deal in production, it becomes irrelevant when the
process exits, but in tests we start and stop many nodes within the same
process so mustn't leak anything.

At this point in shutdown, all HTTP channels are now closed, so it's
sufficient to check whether the channel is open first, and to fail the
listener on the calling thread if not. That's what this commit does.

Closes elastic#104651
@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

💚 Backport successful

Status Branch Result
8.12

@DaveCTurner DaveCTurner deleted the 2024/02/08/http-response-after-close branch February 8, 2024 19:58
DaveCTurner added a commit to DaveCTurner/elasticsearch that referenced this pull request Feb 8, 2024
Similar to elastic#97301, the fix in elastic#105293 was still not quite correct: we
could in principle shut down the transport after checking `isOpen()` but
before sending the message. Applying the same fix as for the transport
layer here.
@DaveCTurner
Copy link
Copy Markdown
Member Author

Ah damn even this isn't quite enough, see #105306.

elasticsearchmachine pushed a commit that referenced this pull request Feb 8, 2024
* Fix leaked HTTP response sent after close (#105293)

Today a `HttpResponse` is always released via a `ChannelPromise` which
means the release happens on a network thread. However, it's possible we
try and send a `HttpResponse` after the node has got far enough through
shutdown that it doesn't have any running network threads left, which
means the response just leaks.

This is no big deal in production, it becomes irrelevant when the
process exits, but in tests we start and stop many nodes within the same
process so mustn't leak anything.

At this point in shutdown, all HTTP channels are now closed, so it's
sufficient to check whether the channel is open first, and to fail the
listener on the calling thread if not. That's what this commit does.

Closes #104651

* Fix backport
@pxsalehi
Copy link
Copy Markdown
Member

pxsalehi commented Feb 9, 2024

@DaveCTurner how did you find out this fix wasn't enough? Was there a test failure?

@DaveCTurner
Copy link
Copy Markdown
Member Author

No, I just took a break and my subconscious told me to take another look. It would have caused test failures tho, just a little rarer than before.

DaveCTurner added a commit that referenced this pull request Feb 9, 2024
Similar to #97301, the fix in #105293 was still not quite correct: we
could in principle shut down the transport after checking `isOpen()` but
before sending the message. Applying the same fix as for the transport
layer here.
DaveCTurner added a commit to DaveCTurner/elasticsearch that referenced this pull request Feb 9, 2024
Similar to elastic#97301, the fix in elastic#105293 was still not quite correct: we
could in principle shut down the transport after checking `isOpen()` but
before sending the message. Applying the same fix as for the transport
layer here.
elasticsearchmachine pushed a commit that referenced this pull request Feb 9, 2024
Similar to #97301, the fix in #105293 was still not quite correct: we
could in principle shut down the transport after checking `isOpen()` but
before sending the message. Applying the same fix as for the transport
layer here.
@DaveCTurner DaveCTurner restored the 2024/02/08/http-response-after-close branch June 17, 2024 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-merge-without-approval Automatically merge pull request when CI checks pass (NB doesn't wait for reviews!) >bug :Distributed/Network Http and internode communication implementations Team:Distributed Meta label for distributed team. v8.12.2 v8.13.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CI] SuggestStatsIT testSimpleStats failing

3 participants