dsmiley commented on code in PR #4829:
URL: https://github.com/apache/solr/pull/4829#discussion_r3916515870


##########
solr/solr-ref-guide/modules/upgrade-notes/pages/major-changes-in-solr-10.adoc:
##########
@@ -103,6 +103,12 @@ Its builder will dynamically detect if solr-jetty is 
available and use that, oth
 CommonParams.QT has been un-deprecated.
 Nonetheless, if your code makes explicit reference to "qt" when constructing a 
standard request, there is usually a better way.
 
+`CloudSolrClient` now retries a failed update only when the transport can 
prove the request never reached the server.
+Previously any communication error, or a 503, caused a retry, which could 
re-send an update that had already been partially applied.
+
+`SolrClient` gains `wasRequestUnsent(Throwable)` and 
`wasCommError(Throwable)`, both defaulting to `false` and overridden per 
transport.

Review Comment:
   I don't think this is worth putting in the ref guide.  It's a detail and 
doesn't change how people use SolrJ.



##########
solr/solrj/src/java/org/apache/solr/client/solrj/SolrClient.java:
##########


Review Comment:
   These seem HttpSolrClient worthy and not generalized to any SolrClient (e.g. 
not EmbeddedSolrServer).  Even not worthy of CloudSolrClient since it's really 
the backing HttpSolrClient, which CSC exposes.



##########
solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java:
##########
@@ -672,31 +669,27 @@ protected Exception doRequest(
       if (!isNonRetryable
           && (rootCause instanceof IOException || rootCause instanceof 
TimeoutException)) {
         ex = (!isZombie) ? makeServerAZombie(baseUrl, e) : e;
-      } else if (isNonRetryable
-          && (isConnectException(rootCause)
-              || SolrException.hasCause(e, RequestNotSentException.class))) {
+      } else if (isNonRetryable && getClient(baseUrl).wasRequestUnsent(e)) {
         // Nothing of the request reached the server, so replaying it 
elsewhere is safe even though
         // it isn't idempotent.
         ex = (!isZombie) ? makeServerAZombie(baseUrl, e) : e;
       } else {
         throw e;
       }
+    } catch (IOException e) {

Review Comment:
   An implicit outcome of SOLR-18402, I think, is to massively simplify catch 
blocks that currently are overly complex.  Adding an IOException here and not 
simplifying or generalizing the previous ones is counter to this direction.



##########
solr/solrj/src/java/org/apache/solr/client/solrj/SolrClient.java:
##########
@@ -1194,12 +1194,27 @@ public final NamedList<Object> request(final 
SolrRequest<?> request)
     return request(request, null);
   }
 
+  /**
+   * Whether the failure proves the request never reached the server, making a 
replay safe even when
+   * the request isn't idempotent. Only the transport can answer this; the 
default is {@code false},
+   * meaning "cannot tell" rather than "the request was sent".
+   */
+  public boolean wasRequestUnsent(Throwable t) {
+    return false;
+  }
+
+  /**
+   * Whether this is a transport-level communication failure rather than a 
response from the server.
+   * Implementations must keep {@link #wasRequestUnsent} a subset of this.
+   */
+  public boolean wasCommError(Throwable t) {
+    return false;
+  }
+

Review Comment:
   I generated this JIRA description with AI, and I did read it.  But I confess 
now (and I recall then as well), I'm confused on the distinction between these 
2 methods.  It's not clear to me why we need a distinction between these two.  
Feel free to help me figure this out ;-)



-- 
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.

To unsubscribe, e-mail: [email protected]

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