You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2018/10/09 12:33:22 UTC

[3/4] httpcomponents-core git commit: Performance optimization: non-blocking message stream handlers to flush message heads early whenever possible

Performance optimization: non-blocking message stream handlers to flush message heads early whenever possible


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/83615503
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/83615503
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/83615503

Branch: refs/heads/master
Commit: 836155036c07b626c56e7388166261d64681c8e4
Parents: f309454
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Tue Oct 9 13:54:41 2018 +0200
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Tue Oct 9 14:30:22 2018 +0200

----------------------------------------------------------------------
 .../impl/nio/AbstractHttp1StreamDuplexer.java   |  8 ++++-
 .../impl/nio/ClientHttp1StreamDuplexer.java     |  7 +++--
 .../http/impl/nio/ClientHttp1StreamHandler.java |  6 ++--
 .../hc/core5/http/impl/nio/FlushMode.java       | 33 ++++++++++++++++++++
 .../core5/http/impl/nio/Http1StreamChannel.java |  2 +-
 .../impl/nio/ServerHttp1StreamDuplexer.java     | 16 +++++++---
 .../http/impl/nio/ServerHttp1StreamHandler.java |  4 +--
 7 files changed, 63 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/83615503/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
index 1121a03..7956b5c 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java
@@ -444,7 +444,10 @@ abstract class AbstractHttp1StreamDuplexer<IncomingMessage extends HttpMessage,
         ioSession.setEvent(SelectionKey.OP_WRITE);
     }
 
-    void commitMessageHead(final OutgoingMessage messageHead, final boolean endStream) throws HttpException, IOException {
+    void commitMessageHead(
+            final OutgoingMessage messageHead,
+            final boolean endStream,
+            final FlushMode flushMode) throws HttpException, IOException {
         outputLock.lock();
         try {
             outgoingMessageWriter.write(messageHead, outbuf);
@@ -462,6 +465,9 @@ abstract class AbstractHttp1StreamDuplexer<IncomingMessage extends HttpMessage,
                 }
             }
             outgoingMessageWriter.reset();
+            if (flushMode == FlushMode.IMMEDIATE) {
+                outbuf.flush(ioSession.channel());
+            }
             ioSession.setEvent(EventMask.WRITE);
         } finally {
             outputLock.unlock();

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/83615503/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
index 6cb59cc..0aa4aa1 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamDuplexer.java
@@ -116,11 +116,14 @@ public class ClientHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
             }
 
             @Override
-            public void submit(final HttpRequest request, final boolean endStream) throws HttpException, IOException {
+            public void submit(
+                    final HttpRequest request,
+                    final boolean endStream,
+                    final FlushMode flushMode) throws HttpException, IOException {
                 if (streamListener != null) {
                     streamListener.onRequestHead(ClientHttp1StreamDuplexer.this, request);
                 }
-                commitMessageHead(request, endStream);
+                commitMessageHead(request, endStream, flushMode);
             }
 
             @Override

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/83615503/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
index d6c606f..cf9329a 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
@@ -154,13 +154,15 @@ class ClientHttp1StreamHandler implements ResourceHolder {
             httpProcessor.process(request, entityDetails, context);
 
             final boolean endStream = entityDetails == null;
-            outputChannel.submit(request, endStream);
-            committedRequest = request;
             if (endStream) {
+                outputChannel.submit(request, endStream, FlushMode.IMMEDIATE);
+                committedRequest = request;
                 requestState = MessageState.COMPLETE;
             } else {
                 final Header h = request.getFirstHeader(HttpHeaders.EXPECT);
                 final boolean expectContinue = h != null && "100-continue".equalsIgnoreCase(h.getValue());
+                outputChannel.submit(request, endStream, expectContinue ? FlushMode.IMMEDIATE : FlushMode.BUFFER);
+                committedRequest = request;
                 if (expectContinue) {
                     requestState = MessageState.ACK;
                     timeout = outputChannel.getSocketTimeout();

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/83615503/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/FlushMode.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/FlushMode.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/FlushMode.java
new file mode 100644
index 0000000..22fcaa4
--- /dev/null
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/FlushMode.java
@@ -0,0 +1,33 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.http.impl.nio;
+
+enum FlushMode {
+
+    IMMEDIATE, BUFFER
+
+}

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/83615503/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/Http1StreamChannel.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/Http1StreamChannel.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/Http1StreamChannel.java
index e211478..3d4bd88 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/Http1StreamChannel.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/Http1StreamChannel.java
@@ -39,7 +39,7 @@ interface Http1StreamChannel<OutgoingMessage extends HttpMessage> extends Conten
 
     void activate() throws HttpException, IOException;
 
-    void submit(OutgoingMessage messageHead, boolean endStream) throws HttpException, IOException;
+    void submit(OutgoingMessage messageHead, boolean endStream, final FlushMode flushMode) throws HttpException, IOException;
 
     void requestOutput();
 

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/83615503/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
index 2db842b..986fed4 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamDuplexer.java
@@ -121,11 +121,14 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
             }
 
             @Override
-            public void submit(final HttpResponse response, final boolean endStream) throws HttpException, IOException {
+            public void submit(
+                    final HttpResponse response,
+                    final boolean endStream,
+                    final FlushMode flushMode) throws HttpException, IOException {
                 if (streamListener != null) {
                     streamListener.onResponseHead(ServerHttp1StreamDuplexer.this, response);
                 }
-                commitMessageHead(response, endStream);
+                commitMessageHead(response, endStream, flushMode);
             }
 
             @Override
@@ -425,10 +428,13 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
         }
 
         @Override
-        public void submit(final HttpResponse response, final boolean endStream) throws HttpException, IOException {
+        public void submit(
+                final HttpResponse response,
+                final boolean endStream,
+                final FlushMode flushMode) throws HttpException, IOException {
             synchronized (this) {
                 if (direct) {
-                    channel.submit(response, endStream);
+                    channel.submit(response, endStream, flushMode);
                 } else {
                     delayedResponse = response;
                     completed = endStream;
@@ -497,7 +503,7 @@ public class ServerHttp1StreamDuplexer extends AbstractHttp1StreamDuplexer<HttpR
             synchronized (this) {
                 direct = true;
                 if (delayedResponse != null) {
-                    channel.submit(delayedResponse, completed);
+                    channel.submit(delayedResponse, completed, completed ? FlushMode.IMMEDIATE : FlushMode.BUFFER);
                     delayedResponse = null;
                 }
             }

http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/83615503/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
----------------------------------------------------------------------
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
index a43b288..cb3fbf6 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1StreamHandler.java
@@ -146,7 +146,7 @@ class ServerHttp1StreamHandler implements ResourceHolder {
                 keepAlive = false;
             }
 
-            outputChannel.submit(response, endStream);
+            outputChannel.submit(response, endStream, endStream ? FlushMode.IMMEDIATE : FlushMode.BUFFER);
             if (endStream) {
                 if (!keepAlive) {
                     outputChannel.close();
@@ -169,7 +169,7 @@ class ServerHttp1StreamHandler implements ResourceHolder {
         if (status < HttpStatus.SC_INFORMATIONAL || status >= HttpStatus.SC_SUCCESS) {
             throw new HttpException("Invalid intermediate response: " + status);
         }
-        outputChannel.submit(response, true);
+        outputChannel.submit(response, true, FlushMode.IMMEDIATE);
     }
 
     private void commitPromise() throws HttpException {