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 2013/03/19 14:12:47 UTC

svn commit: r1458267 - in /httpcomponents/httpcore/trunk/httpcore/src: main/java/org/apache/http/impl/ main/java/org/apache/http/impl/io/ main/java/org/apache/http/impl/pool/ test/java/org/apache/http/impl/ test/java/org/apache/http/impl/io/ test/java/...

Author: olegk
Date: Tue Mar 19 13:12:46 2013
New Revision: 1458267

URL: http://svn.apache.org/r1458267
Log:
 Reduced TCP packet fragmentation for blocking connection

Modified:
    httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/BHttpConnectionBase.java
    httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnection.java
    httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnection.java
    httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/io/SessionOutputBufferImpl.java
    httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java
    httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/SessionOutputBufferMock.java
    httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/io/TestSessionInOutBuffers.java
    httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpClientConnection.java
    httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpServerConnection.java

Modified: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/BHttpConnectionBase.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/BHttpConnectionBase.java?rev=1458267&r1=1458266&r2=1458267&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/BHttpConnectionBase.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/BHttpConnectionBase.java Tue Mar 19 13:12:46 2013
@@ -89,6 +89,7 @@ public class BHttpConnectionBase impleme
      * Creates new instance of BHttpConnectionBase.
      *
      * @param buffersize buffer size. Must be a positive number.
+     * @param fragmentSizeHint fragment size hint.
      * @param chardecoder decoder to be used for decoding HTTP protocol elements.
      *   If <code>null</code> simple type cast will be used for byte to char conversion.
      * @param charencoder encoder to be used for encoding HTTP protocol elements.
@@ -102,6 +103,7 @@ public class BHttpConnectionBase impleme
      */
     protected BHttpConnectionBase(
             final int buffersize,
+            final int fragmentSizeHint,
             final CharsetDecoder chardecoder,
             final CharsetEncoder charencoder,
             final MessageConstraints constraints,
@@ -113,7 +115,7 @@ public class BHttpConnectionBase impleme
         final HttpTransportMetricsImpl outTransportMetrics = new HttpTransportMetricsImpl();
         this.inbuffer = new SessionInputBufferImpl(inTransportMetrics, buffersize, -1,
                 constraints != null ? constraints : MessageConstraints.DEFAULT, chardecoder);
-        this.outbuffer = new SessionOutputBufferImpl(outTransportMetrics, buffersize, -1,
+        this.outbuffer = new SessionOutputBufferImpl(outTransportMetrics, buffersize, fragmentSizeHint,
                 charencoder);
         this.connMetrics = new HttpConnectionMetricsImpl(inTransportMetrics, outTransportMetrics);
         this.incomingContentStrategy = incomingContentStrategy != null ? incomingContentStrategy :

Modified: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnection.java?rev=1458267&r1=1458266&r2=1458267&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnection.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpClientConnection.java Tue Mar 19 13:12:46 2013
@@ -69,6 +69,7 @@ public class DefaultBHttpClientConnectio
      * Creates new instance of DefaultBHttpClientConnection.
      *
      * @param buffersize buffer size. Must be a positive number.
+     * @param fragmentSizeHint fragment size hint.
      * @param chardecoder decoder to be used for decoding HTTP protocol elements.
      *   If <code>null</code> simple type cast will be used for byte to char conversion.
      * @param charencoder encoder to be used for encoding HTTP protocol elements.
@@ -86,6 +87,7 @@ public class DefaultBHttpClientConnectio
      */
     public DefaultBHttpClientConnection(
             final int buffersize,
+            final int fragmentSizeHint,
             final CharsetDecoder chardecoder,
             final CharsetEncoder charencoder,
             final MessageConstraints constraints,
@@ -93,7 +95,7 @@ public class DefaultBHttpClientConnectio
             final ContentLengthStrategy outgoingContentStrategy,
             final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
             final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
-        super(buffersize, chardecoder, charencoder,
+        super(buffersize, fragmentSizeHint, chardecoder, charencoder,
                 constraints, incomingContentStrategy, outgoingContentStrategy);
         this.requestWriter = (requestWriterFactory != null ? requestWriterFactory :
             DefaultHttpRequestWriterFactory.INSTANCE).create(getSessionOutputBuffer());
@@ -106,11 +108,11 @@ public class DefaultBHttpClientConnectio
             final CharsetDecoder chardecoder,
             final CharsetEncoder charencoder,
             final MessageConstraints constraints) {
-        this(buffersize, chardecoder, charencoder, constraints, null, null, null, null);
+        this(buffersize, buffersize, chardecoder, charencoder, constraints, null, null, null, null);
     }
 
     public DefaultBHttpClientConnection(final int buffersize) {
-        this(buffersize, null, null, null, null, null, null, null);
+        this(buffersize, buffersize, null, null, null, null, null, null, null);
     }
 
     protected void onResponseReceived(final HttpResponse response) {

Modified: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnection.java?rev=1458267&r1=1458266&r2=1458267&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnection.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/DefaultBHttpServerConnection.java Tue Mar 19 13:12:46 2013
@@ -68,6 +68,7 @@ public class DefaultBHttpServerConnectio
      * Creates new instance of DefaultBHttpServerConnection.
      *
      * @param buffersize buffer size. Must be a positive number.
+     * @param fragmentSizeHint fragment size hint.
      * @param chardecoder decoder to be used for decoding HTTP protocol elements.
      *   If <code>null</code> simple type cast will be used for byte to char conversion.
      * @param charencoder encoder to be used for encoding HTTP protocol elements.
@@ -85,6 +86,7 @@ public class DefaultBHttpServerConnectio
      */
     public DefaultBHttpServerConnection(
             final int buffersize,
+            final int fragmentSizeHint,
             final CharsetDecoder chardecoder,
             final CharsetEncoder charencoder,
             final MessageConstraints constraints,
@@ -92,7 +94,7 @@ public class DefaultBHttpServerConnectio
             final ContentLengthStrategy outgoingContentStrategy,
             final HttpMessageParserFactory<HttpRequest> requestParserFactory,
             final HttpMessageWriterFactory<HttpResponse> responseWriterFactory) {
-        super(buffersize, chardecoder, charencoder, constraints,
+        super(buffersize, fragmentSizeHint, chardecoder, charencoder, constraints,
                 incomingContentStrategy != null ? incomingContentStrategy :
                     DisallowIdentityContentLengthStrategy.INSTANCE, outgoingContentStrategy);
         this.requestParser = (requestParserFactory != null ? requestParserFactory :
@@ -106,11 +108,11 @@ public class DefaultBHttpServerConnectio
             final CharsetDecoder chardecoder,
             final CharsetEncoder charencoder,
             final MessageConstraints constraints) {
-        this(buffersize, chardecoder, charencoder, constraints, null, null, null, null);
+        this(buffersize, buffersize, chardecoder, charencoder, constraints, null, null, null, null);
     }
 
     public DefaultBHttpServerConnection(final int buffersize) {
-        this(buffersize, null, null, null, null, null, null, null);
+        this(buffersize, buffersize, null, null, null, null, null, null, null);
     }
 
     protected void onRequestReceived(final HttpRequest request) {

Modified: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/io/SessionOutputBufferImpl.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/io/SessionOutputBufferImpl.java?rev=1458267&r1=1458266&r2=1458267&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/io/SessionOutputBufferImpl.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/io/SessionOutputBufferImpl.java Tue Mar 19 13:12:46 2013
@@ -61,7 +61,7 @@ public class SessionOutputBufferImpl imp
 
     private final HttpTransportMetricsImpl metrics;
     private final ByteArrayBuffer buffer;
-    private final int minChunkLimit;
+    private final int fragementSizeHint;
     private final CharsetEncoder encoder;
 
     private OutputStream outstream;
@@ -72,25 +72,23 @@ public class SessionOutputBufferImpl imp
      *
      * @param metrics HTTP transport metrics.
      * @param buffersize buffer size. Must be a positive number.
-     * @param minChunkLimit size limit below which data chunks should be buffered in memory
-     *   in order to minimize native method invocations on the underlying network socket.
-     *   The optimal value of this parameter can be platform specific and defines a trade-off
-     *   between performance of memory copy operations and that of native method invocation.
-     *   If negative default chunk limited will be used.
+     * @param fragementSizeHint fragment size hint defining a minimal size of a fragment
+     *   that should be written out directly to the socket bypassing the session buffer.
+     *   Value <code>0</code> disables fragment buffering.
      * @param charencoder charencoder to be used for encoding HTTP protocol elements.
      *   If <code>null</code> simple type cast will be used for char to byte conversion.
      */
     public SessionOutputBufferImpl(
             final HttpTransportMetricsImpl metrics,
             final int buffersize,
-            final int minChunkLimit,
+            final int fragementSizeHint,
             final CharsetEncoder charencoder) {
         super();
         Args.positive(buffersize, "Buffer size");
         Args.notNull(metrics, "HTTP transport metrcis");
         this.metrics = metrics;
         this.buffer = new ByteArrayBuffer(buffersize);
-        this.minChunkLimit = minChunkLimit >= 0 ? minChunkLimit : 512;
+        this.fragementSizeHint = fragementSizeHint >= 0 ? fragementSizeHint : 0;
         this.encoder = charencoder;
     }
 
@@ -146,7 +144,7 @@ public class SessionOutputBufferImpl imp
         // Do not want to buffer large-ish chunks
         // if the byte array is larger then MIN_CHUNK_LIMIT
         // write it directly to the output stream
-        if (len > this.minChunkLimit || len > this.buffer.capacity()) {
+        if (len > this.fragementSizeHint || len > this.buffer.capacity()) {
             // flush the buffer
             flushBuffer();
             // write directly to the out stream
@@ -172,10 +170,15 @@ public class SessionOutputBufferImpl imp
     }
 
     public void write(final int b) throws IOException {
-        if (this.buffer.isFull()) {
+        if (this.fragementSizeHint > 0) {
+            if (this.buffer.isFull()) {
+                flushBuffer();
+            }
+            this.buffer.append(b);
+        } else {
             flushBuffer();
+            this.outstream.write(b);
         }
-        this.buffer.append(b);
     }
 
     /**

Modified: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java?rev=1458267&r1=1458266&r2=1458267&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnFactory.java Tue Mar 19 13:12:46 2013
@@ -171,9 +171,12 @@ public class BasicConnFactory implements
             charencoder.onMalformedInput(malformedInputAction);
             charencoder.onUnmappableCharacter(unmappableInputAction);
         }
-        final DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(8 * 1024,
+        final DefaultBHttpClientConnection conn = new DefaultBHttpClientConnection(
+                this.cconfig.getBufferSize(),
+                this.cconfig.getFragmentSizeHint(),
                 chardecoder, charencoder,
-                this.cconfig.getMessageConstraints());
+                this.cconfig.getMessageConstraints(),
+                null, null, null, null);
         conn.bind(socket);
         return conn;
     }

Modified: httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/SessionOutputBufferMock.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/SessionOutputBufferMock.java?rev=1458267&r1=1458266&r2=1458267&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/SessionOutputBufferMock.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/SessionOutputBufferMock.java Tue Mar 19 13:12:46 2013
@@ -47,9 +47,9 @@ public class SessionOutputBufferMock ext
     public SessionOutputBufferMock(
             final ByteArrayOutputStream buffer,
             final int buffersize,
-            final int minChunkLimit,
+            final int fragementSizeHint,
             final CharsetEncoder encoder) {
-        super(new HttpTransportMetricsImpl(), buffersize, minChunkLimit, encoder);
+        super(new HttpTransportMetricsImpl(), buffersize, fragementSizeHint, encoder);
         bind(buffer);
         this.buffer = buffer;
     }
@@ -57,21 +57,22 @@ public class SessionOutputBufferMock ext
     public SessionOutputBufferMock(
             final ByteArrayOutputStream buffer,
             final int buffersize) {
-        this(buffer, buffersize, -1, null);
+        this(buffer, buffersize, buffersize, null);
     }
 
     public SessionOutputBufferMock(
             final CharsetEncoder encoder) {
-        this(new ByteArrayOutputStream(), BUFFER_SIZE, -1, encoder);
+        this(new ByteArrayOutputStream(), BUFFER_SIZE, BUFFER_SIZE, encoder);
     }
 
     public SessionOutputBufferMock(
             final Charset charset) {
-        this(new ByteArrayOutputStream(), BUFFER_SIZE, -1, charset != null ? charset.newEncoder() : null);
+        this(new ByteArrayOutputStream(), BUFFER_SIZE, BUFFER_SIZE,
+                charset != null ? charset.newEncoder() : null);
     }
 
     public SessionOutputBufferMock(final ByteArrayOutputStream buffer) {
-        this(buffer, BUFFER_SIZE, -1, null);
+        this(buffer, BUFFER_SIZE, BUFFER_SIZE, null);
     }
 
     public SessionOutputBufferMock() {

Modified: httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/io/TestSessionInOutBuffers.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/io/TestSessionInOutBuffers.java?rev=1458267&r1=1458266&r2=1458267&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/io/TestSessionInOutBuffers.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/impl/io/TestSessionInOutBuffers.java Tue Mar 19 13:12:46 2013
@@ -27,6 +27,7 @@
 
 package org.apache.http.impl.io;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.nio.charset.CharacterCodingException;
 import java.nio.charset.CharsetDecoder;
@@ -41,6 +42,7 @@ import org.apache.http.io.HttpTransportM
 import org.apache.http.util.CharArrayBuffer;
 import org.junit.Assert;
 import org.junit.Test;
+import org.mockito.Mockito;
 
 public class TestSessionInOutBuffers {
 
@@ -328,6 +330,33 @@ public class TestSessionInOutBuffers {
     }
 
     @Test
+    public void testWriteSmallFragmentBuffering() throws Exception {
+        final ByteArrayOutputStream outstream = Mockito.spy(new ByteArrayOutputStream());
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock(outstream, 16, 16, null);
+        outbuffer.write(1);
+        outbuffer.write(2);
+        outbuffer.write(new byte[] {1, 2});
+        outbuffer.write(new byte[] {3, 4});
+        outbuffer.flush();
+        Mockito.verify(outstream, Mockito.times(1)).write(
+                Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt());
+        Mockito.verify(outstream, Mockito.never()).write(Mockito.anyInt());
+    }
+
+    @Test
+    public void testWriteSmallFragmentNoBuffering() throws Exception {
+        final ByteArrayOutputStream outstream = Mockito.spy(new ByteArrayOutputStream());
+        final SessionOutputBufferMock outbuffer = new SessionOutputBufferMock(outstream, 16, 0, null);
+        outbuffer.write(1);
+        outbuffer.write(2);
+        outbuffer.write(new byte[] {1, 2});
+        outbuffer.write(new byte[] {3, 4});
+        Mockito.verify(outstream, Mockito.times(2)).write(
+                Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt());
+        Mockito.verify(outstream, Mockito.times(2)).write(Mockito.anyInt());
+    }
+
+    @Test
     public void testLineLimit() throws Exception {
         final String s = "a very looooooooooooooooooooooooooooooooooooooong line\r\n     ";
         final byte[] tmp = s.getBytes("US-ASCII");

Modified: httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpClientConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpClientConnection.java?rev=1458267&r1=1458266&r2=1458267&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpClientConnection.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpClientConnection.java Tue Mar 19 13:12:46 2013
@@ -57,6 +57,7 @@ public class LoggingBHttpClientConnectio
 
     public LoggingBHttpClientConnection(
             final int buffersize,
+            final int fragmentSizeHint,
             final CharsetDecoder chardecoder,
             final CharsetEncoder charencoder,
             final MessageConstraints constraints,
@@ -64,7 +65,7 @@ public class LoggingBHttpClientConnectio
             final ContentLengthStrategy outgoingContentStrategy,
             final HttpMessageWriterFactory<HttpRequest> requestWriterFactory,
             final HttpMessageParserFactory<HttpResponse> responseParserFactory) {
-        super(buffersize, chardecoder, charencoder,
+        super(buffersize, fragmentSizeHint, chardecoder, charencoder,
                 constraints, incomingContentStrategy, outgoingContentStrategy,
                 requestWriterFactory, responseParserFactory);
         this.id = "http-outgoing-" + COUNT.incrementAndGet();
@@ -74,7 +75,7 @@ public class LoggingBHttpClientConnectio
     }
 
     public LoggingBHttpClientConnection(final int buffersize) {
-        this(buffersize, null, null, null, null, null, null, null);
+        this(buffersize, buffersize, null, null, null, null, null, null, null);
     }
 
     @Override

Modified: httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpServerConnection.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpServerConnection.java?rev=1458267&r1=1458266&r2=1458267&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpServerConnection.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/test/java/org/apache/http/testserver/LoggingBHttpServerConnection.java Tue Mar 19 13:12:46 2013
@@ -57,6 +57,7 @@ public class LoggingBHttpServerConnectio
 
     public LoggingBHttpServerConnection(
             final int buffersize,
+            final int fragmentSizeHint,
             final CharsetDecoder chardecoder,
             final CharsetEncoder charencoder,
             final MessageConstraints constraints,
@@ -64,7 +65,7 @@ public class LoggingBHttpServerConnectio
             final ContentLengthStrategy outgoingContentStrategy,
             final HttpMessageParserFactory<HttpRequest> requestParserFactory,
             final HttpMessageWriterFactory<HttpResponse> responseWriterFactory) {
-        super(buffersize, chardecoder, charencoder, constraints,
+        super(buffersize, fragmentSizeHint, chardecoder, charencoder, constraints,
                 incomingContentStrategy, outgoingContentStrategy,
                 requestParserFactory, responseWriterFactory);
         this.id = "http-incoming-" + COUNT.incrementAndGet();
@@ -74,7 +75,7 @@ public class LoggingBHttpServerConnectio
     }
 
     public LoggingBHttpServerConnection(final int buffersize) {
-        this(buffersize, null, null, null, null, null, null, null);
+        this(buffersize, buffersize, null, null, null, null, null, null, null);
     }
 
     @Override