Skip to content

Conversation

Tim-Brooks
Copy link
Contributor

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

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.
@Tim-Brooks Tim-Brooks added :Distributed Coordination/Network Http and internode communication implementations >bug review v6.0.0 v6.1.0 labels Aug 15, 2017
@Tim-Brooks
Copy link
Contributor Author

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

Copy link
Member

@jasontedor jasontedor left a 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());
Copy link
Member

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

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?

Copy link
Contributor Author

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();
        }
Copy link
Contributor Author

@Tim-Brooks Tim-Brooks Aug 15, 2017

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

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

Copy link
Contributor Author

@Tim-Brooks Tim-Brooks Aug 15, 2017

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.

Copy link
Member

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.

Copy link
Contributor

@s1monw s1monw left a 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();
Copy link
Contributor

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?

@jasontedor
Copy link
Member

@tbrooks8 I updated the labels, I think this should be taken to 5.6 too.

@jasontedor jasontedor added v5.6.1 and removed v5.6.0 labels Aug 16, 2017
@Tim-Brooks Tim-Brooks merged commit f69cc78 into elastic:master Aug 16, 2017
Tim-Brooks added a commit that referenced this pull request Aug 16, 2017
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.
Tim-Brooks added a commit that referenced this pull request Aug 16, 2017
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.
Tim-Brooks added a commit that referenced this pull request Aug 16, 2017
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.
@Tim-Brooks Tim-Brooks added v5.6.0 and removed v5.6.1 labels Aug 16, 2017
@Tim-Brooks
Copy link
Contributor Author

Merged and cherry-picked onto 6.x, 6.0, and 5.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
5 participants