You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ff...@apache.org on 2018/10/26 03:13:10 UTC

[cxf] 01/02: fix: handle connectionRequestTimeout in AsyncHTTPConduitFactory

This is an automated email from the ASF dual-hosted git repository.

ffang pushed a commit to branch 3.2.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit 8823224a33e0ad7679e8371df2846a14c0c7b1bc
Author: gyoetam <gy...@users.noreply.github.com>
AuthorDate: Wed Oct 24 11:02:31 2018 +0200

    fix: handle connectionRequestTimeout in AsyncHTTPConduitFactory
    
    Motivation: if connections are contended towards a slow target, it may make sense
    to set connectionTimeout and connectionRequestTimeout to values much lower than
    the receiveTimeout. Expected client behavior is to receive an error if a connection
    does not become available within connectionRequestTimeout. Current behavior however
    is that the error is only received after up to receiveTimeout has passed, when a
    current request to the target has finished and the connection is released or returned
    to the pool.
    
    Fix: instead of only checking expired leases when a connection becomes available,
    periodically check them in the same thread that checks idle connections as
    well. This makes sure that an error is returned to the client after
    a maximum of connectionRequestTimeout + selectTimeout.
    
    As a side effect, PoolingNHttpClientConnectionManager logs a debug level message
    at every selectTimeout interval - this should be suppressed by the logging framework.
    
    (cherry picked from commit a5fcbb30d9a6f6e082061a1947c3ce9da29c40e4)
---
 .../http/asyncclient/AsyncHTTPConduitFactory.java  | 26 +++++++++++++---------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduitFactory.java b/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduitFactory.java
index d616dda..15445bc 100644
--- a/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduitFactory.java
+++ b/rt/transports/http-hc/src/main/java/org/apache/cxf/transport/http/asyncclient/AsyncHTTPConduitFactory.java
@@ -375,11 +375,9 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
         client = httpAsyncClientBuilder.build();
         // Start the client thread
         client.start();
-        if (this.connectionTTL == 0) {
-            //if the connection does not have an expiry deadline
-            //use the ConnectionMaxIdle to close the idle connection
-            new CloseIdleConnectionThread(connectionManager, client).start();
-        }
+        //Always start the idle checker thread to validate pending requests and
+        //use the ConnectionMaxIdle to close the idle connection
+        new CloseIdleConnectionThread(connectionManager, client).start();
     }
 
     //provide a hook to customize the builder
@@ -401,20 +399,28 @@ public class AsyncHTTPConduitFactory implements HTTPConduitFactory {
 
         public CloseIdleConnectionThread(PoolingNHttpClientConnectionManager connMgr,
                                      CloseableHttpAsyncClient client) {
-            super();
+            super("CXFCloseIdleConnectionThread");
             this.connMgr = connMgr;
             this.client = client;
         }
 
         @Override
         public void run() {
+            long nextIdleCheck = System.currentTimeMillis() + connectionMaxIdle;
             try {
                 while (client.isRunning()) {
                     synchronized (this) {
-                        sleep(connectionMaxIdle);
-                        // close connections
-                        // that have been idle longer than specified connectionMaxIdle
-                        connMgr.closeIdleConnections(connectionMaxIdle, TimeUnit.MILLISECONDS);
+                        sleep(selectInterval);
+                        // make sure pending leases fail in a timely manner,
+                        // not just when a connection becomes available
+                        connMgr.validatePendingRequests();
+
+                        if (connectionMaxIdle > 0 && System.currentTimeMillis() >= nextIdleCheck) {
+                            nextIdleCheck += connectionMaxIdle;
+                            // close connections
+                            // that have been idle longer than specified connectionMaxIdle
+                            connMgr.closeIdleConnections(connectionMaxIdle, TimeUnit.MILLISECONDS);
+                        }
                     }
                 }
             } catch (InterruptedException ex) {