carterkozak commented on a change in pull request #206:
URL: 
https://github.com/apache/httpcomponents-core/pull/206#discussion_r464089770



##########
File path: 
httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultBHttpClientConnection.java
##########
@@ -157,41 +198,40 @@ public void sendRequestEntity(final ClassicHttpRequest 
request) throws HttpExcep
         try (final OutputStream outStream = createContentOutputStream(
                 len, this.outbuffer, new OutputStream() {
 
-                    final boolean ssl = socketHolder.getSocket() instanceof 
SSLSocket;
-                    final InputStream socketInputStream = 
socketHolder.getInputStream();
                     final OutputStream socketOutputStream = 
socketHolder.getOutputStream();
+                    final InputStream socketInputStream = 
socketHolder.getInputStream();
 
                     long totalBytes = 0;
-                    long chunks = -1;
 
-                    void checkForEarlyResponse() throws IOException {
-                        final long n = totalBytes / (8 * 1024);
-                        if (n > chunks) {
-                            chunks = n;
-                            if (ssl ? isDataAvailable(Timeout.ONE_MILLISECOND) 
: (socketInputStream.available() > 0)) {
-                                throw new ResponseOutOfOrderException();
-                            }
+                    void checkForEarlyResponse(final long totalBytesSent, 
final int nextWriteSize) throws IOException {
+                        if (responseOutOfOrderStrategy.checkForEarlyResponse(
+                                DefaultBHttpClientConnection.this,
+                                request,
+                                socketInputStream,
+                                totalBytesSent,
+                                nextWriteSize)) {
+                            throw new ResponseOutOfOrderException();
                         }
                     }
 
                     @Override
                     public void write(final byte[] b) throws IOException {
+                        checkForEarlyResponse(totalBytes, b.length);

Review comment:
       I don't think this change behavior, previously the algorithm was:
   
   1. accumulate the next write length with the total length
   2. check for response using the updated totalBytes value
   3. write to the socket
   
   Now we do the same thing, with the minor change that we pass both the 
pre-write value and the length separately, instead of the sum:
   
   1.  check for response using the previous totalBytes and write length values
   2. accumulate the next write length with the total length
   3. write to the socket
   
   This OutputStream is entirely encapsulated within 
`DefaultBHttpClientConnection.sendRequestEntity`. Regardless of the headers, 
`totalBytes` only tracks the entity size, starting at zero. In the previous 
implementation `chunks` was initialized at `-1` which forces the first write to 
check for a response prior to checking the socket, even if the length is zero.

##########
File path: 
httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultResponseOutOfOrderStrategy.java
##########
@@ -0,0 +1,78 @@
+/*
+ * ====================================================================
+ * 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.io;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.io.HttpClientConnection;
+import org.apache.hc.core5.http.io.ResponseOutOfOrderStrategy;
+import org.apache.hc.core5.util.Timeout;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Default {@link ResponseOutOfOrderStrategy} implementation which checks for 
premature responses every 8 KiB based
+ * on testing using values between 4 KiB and 128 KiB. This is optimized for 
correctness and results in a maximum
+ * upload speed of 8 MiB/s.
+ *
+ * @since 5.1
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+public final class DefaultResponseOutOfOrderStrategy implements 
ResponseOutOfOrderStrategy {
+
+    public static final DefaultResponseOutOfOrderStrategy INSTANCE = new 
DefaultResponseOutOfOrderStrategy();
+
+    private static final int CHUNK_SIZE = 8 * 1024;
+
+    @Override
+    public boolean checkForEarlyResponse(
+            final HttpClientConnection connection,
+            final ClassicHttpRequest request,
+            final InputStream socketInputStream,
+            final long totalBytesSent,
+            final long nextWriteSize) throws IOException {
+        if (totalBytesSent == 0 || nextWriteBeginsNewChunk(totalBytesSent, 
nextWriteSize)) {
+            final boolean ssl = connection.getSSLSession() != null;
+            return ssl ? connection.isDataAvailable(Timeout.ONE_MILLISECOND) : 
(socketInputStream.available() > 0);
+        }
+        return false;
+    }
+
+    private static boolean nextWriteBeginsNewChunk(final long totalBytesSent, 
final long nextWriteSize) {

Review comment:
       I've updated it to your `nextWriteStartsNewChunk` suggestion, thanks!

##########
File path: 
httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultResponseOutOfOrderStrategy.java
##########
@@ -0,0 +1,78 @@
+/*
+ * ====================================================================
+ * 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.io;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.io.HttpClientConnection;
+import org.apache.hc.core5.http.io.ResponseOutOfOrderStrategy;
+import org.apache.hc.core5.util.Timeout;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Default {@link ResponseOutOfOrderStrategy} implementation which checks for 
premature responses every 8 KiB based
+ * on testing using values between 4 KiB and 128 KiB. This is optimized for 
correctness and results in a maximum
+ * upload speed of 8 MiB/s.
+ *
+ * @since 5.1
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+public final class DefaultResponseOutOfOrderStrategy implements 
ResponseOutOfOrderStrategy {
+
+    public static final DefaultResponseOutOfOrderStrategy INSTANCE = new 
DefaultResponseOutOfOrderStrategy();
+
+    private static final int CHUNK_SIZE = 8 * 1024;
+
+    @Override
+    public boolean checkForEarlyResponse(

Review comment:
       > There are only two hard things in Computer Science: cache invalidation 
and naming things.
   > -- Phil Karlton
   
   Perhaps `isEarlyResponseAvailable` or `isEarlyResponseDetected`? I think I 
prefer `isEarlyResponseDetected` because the no-op implementation may not 
detect an early response even if one is available.

##########
File path: 
httpcore5/src/main/java/org/apache/hc/core5/http/impl/io/DefaultResponseOutOfOrderStrategy.java
##########
@@ -0,0 +1,78 @@
+/*
+ * ====================================================================
+ * 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.io;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.io.HttpClientConnection;
+import org.apache.hc.core5.http.io.ResponseOutOfOrderStrategy;
+import org.apache.hc.core5.util.Timeout;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Default {@link ResponseOutOfOrderStrategy} implementation which checks for 
premature responses every 8 KiB based
+ * on testing using values between 4 KiB and 128 KiB. This is optimized for 
correctness and results in a maximum
+ * upload speed of 8 MiB/s.
+ *
+ * @since 5.1
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+public final class DefaultResponseOutOfOrderStrategy implements 
ResponseOutOfOrderStrategy {

Review comment:
       That's a good idea, I've implemented it.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to