-
Notifications
You must be signed in to change notification settings - Fork 25.5k
Release pipelined http responses on close #26226
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
Conversation
Right now it is possible for the `HttpPipeliningHandler` to queue pipelined responses. On channel close, we do not clear and release these responses. This commit releases the responses and completes the promise.
@jasontedor Is there something that I am missing here and this is not necessary? I do not see anywhere else where these would be released. |
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 good catch @tbrooks8, I left one piece of feedback.
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { | ||
for (HttpPipelinedResponse pipelinedResponse : holdingQueue) { | ||
pipelinedResponse.release(); | ||
pipelinedResponse.promise().setFailure(new ClosedChannelException()); |
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.
Only use one ClosedChannelException
?
|
||
@Override | ||
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { | ||
ClosedChannelException closedChannelException = new ClosedChannelException(); |
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.
Maybe guard this and the loop with a check that the holding queue is not empty?
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'm not exactly sure what you mean. Do you mean something like this:
synchronized (holdingQueue) {
for (HttpPipelinedResponse pipelinedResponse : holdingQueue) {
pipelinedResponse.release();
pipelinedResponse.promise().setFailure(closedChannelException);
}
holdingQueue.clear();
}
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.
Or, I guess you mean this?
synchronized (holdingQueue) {
while (holdingQueue.isEmpty() == false) {
HttpPipelinedResponse pipelinedResponse = holdingQueue.poll();
pipelinedResponse.release();
pipelinedResponse.promise().setFailure(closedChannelException);
}
}
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 the synchronization is necessary (I think it can actually all be removed from this class) but let's put that aside for now as a separate issue.
I meant:
diff --git a/modules/transport-netty4/src/main/java/org/elasticsearch/http/netty4/pipelining/HttpPipeliningHandler.java b/modules/transport-netty4/src/main/java/org/elasticsearch/http/netty4/pipelining/HttpPipeliningHandler.java
index c09099a221..e9d99378e2 100644
--- a/modules/transport-netty4/src/main/java/org/elasticsearch/http/netty4/pipelining/HttpPipeliningHandler.java
+++ b/modules/transport-netty4/src/main/java/org/elasticsearch/http/netty4/pipelining/HttpPipeliningHandler.java
@@ -123,10 +123,12 @@ public class HttpPipeliningHandler extends ChannelDuplexHandler {
@Override
public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
- ClosedChannelException closedChannelException = new ClosedChannelException();
- for (HttpPipelinedResponse pipelinedResponse : holdingQueue) {
- pipelinedResponse.release();
- pipelinedResponse.promise().setFailure(closedChannelException);
+ if (!holdingQueue.isEmpty()) {
+ final ClosedChannelException closedChannelException = new ClosedChannelException();
+ for (final HttpPipelinedResponse pipelinedResponse : holdingQueue) {
+ pipelinedResponse.release();
+ pipelinedResponse.promise().setFailure(closedChannelException);
+ }
}
ctx.close(promise);
}
(and sure, we can add the synchronized block for now until I get around to investigating removing it).
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.
Okay. I will make a change based on that. And I agree that synchronization is not necessary (as it should probably be unnecessary in the write method). I just was confused by what you meant by guard.
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.
Yeah that's what I mean by removing it completely from this class. Sorry for the confusion.
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.
left one question LGTM though
ClosedChannelException closedChannelException = new ClosedChannelException(); | ||
HttpPipelinedResponse pipelinedResponse; | ||
while ((pipelinedResponse = holdingQueue.poll()) != null) { | ||
pipelinedResponse.release(); |
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.
should we catch here and continue in the case of a failure?
@tbrooks8 I updated the labels, I think this should be taken to 5.6 too. |
Right now it is possible for the `HttpPipeliningHandler` to queue pipelined responses. On channel close, we do not clear and release these responses. This commit releases the responses and completes the promise.
Right now it is possible for the `HttpPipeliningHandler` to queue pipelined responses. On channel close, we do not clear and release these responses. This commit releases the responses and completes the promise.
Right now it is possible for the `HttpPipeliningHandler` to queue pipelined responses. On channel close, we do not clear and release these responses. This commit releases the responses and completes the promise.
Merged and cherry-picked onto 6.x, 6.0, and 5.6 |
Right now it is possible for the
HttpPipeliningHandler
to queuepipelined responses. On channel close, we do not clear and release these
responses. This commit releases the responses and completes the promises.