You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by dw...@apache.org on 2020/01/03 13:39:38 UTC

[lucene-solr] 01/02: SOLR-13778: Solrj client will retry requests on SSLException with a suppressed SocketException (very likely a hard-closed socket connection)

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

dweiss pushed a commit to branch branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git

commit 2b00d633a5805bf75eb594688e9dd0a4255b02be
Author: Dawid Weiss <dw...@apache.org>
AuthorDate: Fri Jan 3 14:12:08 2020 +0100

    SOLR-13778: Solrj client will retry requests on SSLException with a suppressed SocketException (very likely a hard-closed socket connection)
---
 solr/CHANGES.txt                                   |  3 ++
 .../solrj/impl/SolrHttpRequestRetryHandler.java    | 36 ++++++++++++++++------
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index d744524..306df7e 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -135,6 +135,9 @@ Other Changes
 
 * SOLR-14091: Remove deprecated soLingerTime when configuring Jetty connector (Matthias Krueger via Kevin Risden)
 
+* SOLR-13778: Solrj client will retry requests on SSLException with a suppressed SocketException
+  (very likely a hard-closed socket connection).
+
 ==================  8.4.0 ==================
 
 Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release.
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/SolrHttpRequestRetryHandler.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/SolrHttpRequestRetryHandler.java
index f5b1b2a..ec8842b 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/SolrHttpRequestRetryHandler.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/SolrHttpRequestRetryHandler.java
@@ -20,11 +20,13 @@ import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.lang.invoke.MethodHandles;
 import java.net.ConnectException;
+import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
+import java.util.function.Predicate;
 
 import javax.net.ssl.SSLException;
 
@@ -34,6 +36,7 @@ import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.client.protocol.HttpClientContext;
 import org.apache.http.impl.client.RequestWrapper;
 import org.apache.http.protocol.HttpContext;
+import org.apache.solr.client.solrj.util.Constants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,7 +65,7 @@ public class SolrHttpRequestRetryHandler implements HttpRequestRetryHandler {
   protected SolrHttpRequestRetryHandler(final int retryCount, final Collection<Class<? extends IOException>> clazzes) {
     super();
     this.retryCount = retryCount;
-    this.nonRetriableClasses = new HashSet<Class<? extends IOException>>();
+    this.nonRetriableClasses = new HashSet<>();
     for (final Class<? extends IOException> clazz : clazzes) {
       this.nonRetriableClasses.add(clazz);
     }
@@ -108,17 +111,12 @@ public class SolrHttpRequestRetryHandler implements HttpRequestRetryHandler {
       log.debug("Do not retry, over max retry count");
       return false;
     }
-    if (this.nonRetriableClasses.contains(exception.getClass())) {
+
+    if (!isRetriable(exception)) {
       log.debug("Do not retry, non retriable class {}", exception.getClass().getName());
       return false;
-    } else {
-      for (final Class<? extends IOException> rejectException : this.nonRetriableClasses) {
-        if (rejectException.isInstance(exception)) {
-          log.debug("Do not retry, non retriable class {}", exception.getClass().getName());
-          return false;
-        }
-      }
     }
+
     final HttpClientContext clientContext = HttpClientContext.adapt(context);
     final HttpRequest request = clientContext.getRequest();
     
@@ -135,7 +133,25 @@ public class SolrHttpRequestRetryHandler implements HttpRequestRetryHandler {
     log.debug("Do not retry, no allow rules matched");
     return false;
   }
-  
+
+  private boolean isRetriable(IOException exception) {
+    // Workaround for "recv failed" issue on hard-aborted sockets on Windows
+    // (and other operating systems, possibly).
+    // https://issues.apache.org/jira/browse/SOLR-13778
+    if (exception instanceof SSLException &&
+        Arrays.stream(exception.getSuppressed()).anyMatch((t) -> t instanceof SocketException)) {
+      return true;
+    }
+
+    // Fast check for exact class followed by slow-check with instanceof.
+    if (nonRetriableClasses.contains(exception.getClass())
+        || nonRetriableClasses.stream().anyMatch(rejectException -> rejectException.isInstance(exception))) {
+      return false;
+    }
+
+    return true;
+  }
+
   public int getRetryCount() {
     return retryCount;
   }