-
Notifications
You must be signed in to change notification settings - Fork 674
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SOLR-16505: Switch UpdateShardHandler.getRecoveryOnlyHttpClient to Jetty HTTP2 #2276
SOLR-16505: Switch UpdateShardHandler.getRecoveryOnlyHttpClient to Jetty HTTP2 #2276
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The addition of the test is really nice.
solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
Outdated
Show resolved
Hide resolved
solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
Outdated
Show resolved
Hide resolved
@@ -133,16 +135,25 @@ public UpdateShardHandler(UpdateShardHandlerConfig cfg) { | |||
DistributedUpdateProcessor.DISTRIB_FROM, | |||
DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM); | |||
Http2SolrClient.Builder updateOnlyClientBuilder = new Http2SolrClient.Builder(); | |||
Http2SolrClient.Builder recoveryOnlyClientBuilder = new Http2SolrClient.Builder(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Come to think of it, updateOnly & recoveryOnly clients are configured the same except for withTheseParamNamesInTheUrl
but it's benign to have that shared. Ultimately, the point I think is for both clients to be separated so that saturation in one (particularly updates) doesn't block the other (recovery). Hopefully I can get Mark Miller to weigh in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CC @markrmiller
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@markrmiller do you recall why there are separate clients for "updateOnly" vs "recoveryOnly"?
solr/core/src/test/org/apache/solr/cloud/RecoveryStrategyStressTest.java
Show resolved
Hide resolved
solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
Outdated
Show resolved
Hide resolved
Thank you @dsmiley for reviewing this PR... I'm excited for the work @iamsanjay has been doing, and I do NOT feel comfortable reviewing/merging code in this area ;-) |
I was thinking about the executor in the Http2SolrClient class. What is the issue?
Solution
Also In this option there will be code to check wh
@dsmiley wdyt? I have changed the code to implement the second option for now. @stillalex I see that we transferred some properties from older Http2SolrClient as we call |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! This really shows how setting out to accomplish one goal can shine a light on some issues to make improvements tangential to the affected code.
@dsmiley I was working on IndexFetcher to change their client to Http2SolrClient. Suddenly all the request in IndexFetcher started failing due to authentication issue. Further inspection revealed that the listener required for Auth is not registered for recoveryOnlyClient. Interestingly, no calls in RecoveryStrategy requires Auth, and therefore no request failed there. Below is the code, that called on updateOnlyClient to register the Auth listener. solr/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java Lines 317 to 319 in 1c6798b
However, only calling this method for recoveryOnlyClient won't work. As recreating Http2SolrClient using withHttpClient won't pass on listeners. Basically same issue that we have faced with Executors. |
Thanks for digging into the authentication issue further; this is shining a light on an issue I was vaguely aware of but now I can see it directly. And I'm so glad there are tests; I thought it wasn't tested. Can you name one please? One thing will help; stop excessive creation of new SolrClient instances when we can re-use the same one that is configured with this auth listener thing. Thus don't have fields on classes that hold an HttpClient (we'll deem this bad/questionable practice); instead hold an Http2SolrClient. If due to customized timeouts we need a new Http2SolrClient, we could ensure that the builder withHttpClient(http2SolrClient) copies listeners (and anything else like an executor; why not). That could be its own JIRA. |
TestPullReplicaWithAuth.testPKIAuthWorksForPullReplication is the one. On a side note, How about we rethink the design decorating the request. Right now, we recreate the Http2SolrClient to override socketTimeout and connTimeout. Instead of recreating Http2SolrClient, we introduced another method which would override Timeouts.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a reference to this file from the test; am I missing something?
If this is actually used, then please consider instead modifying your test to manipulate the temp config files so that we don't have yet another test config file to maintain. For an example of this technique, see org.apache.solr.search.TestCpuAllowedLimit#createConfigSet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won't push this point further because your ...WithAuth test uses ReplicationTestHelper.SolrInstance
which has sone conveniences and I'm not sure how compatible it is with my suggestion.
solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
Show resolved
Hide resolved
Below test failed!
Exception
git bisect 61a67c0 CC @noblepaul |
@@ -1878,7 +1870,6 @@ private int fetchPackets(FastInputStream fis) throws Exception { | |||
log.debug("Fetched and wrote {} bytes of file: {}", bytesDownloaded, fileName); | |||
// errorCount is always set to zero after a successful packet | |||
errorCount = 0; | |||
if (bytesDownloaded >= size) return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did a git blame and found: SOLR-14299 IndexFetcher doesn't reset count to 0 after the last packet is received
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That issue merely moved this code slightly; it didn't introduce it. Anyway, I suppose this code potentially prematurely exited before reading the whole stream, and that's why you removed it?
log.warn("No content received for file: {}", fileName); | ||
return NO_CONTENT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
at least an assert (or comment) communicating this is unexpected
@@ -845,6 +852,13 @@ public static class Builder | |||
|
|||
protected Long keyStoreReloadIntervalSecs; | |||
|
|||
public Http2SolrClient.Builder withListenerFactory(List<HttpListenerFactory> listenerFactory) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@epugh I know you worked on SolrClient immutability efforts. Here, specific to Http2SolrClient, the "listenerFactory" list can now be set on the builder. The setter should probably also be marked Deprecated. Do you think this should be separated to another PR?
solr/core/src/test-files/solr/collection1/conf/solrconfig-follower-auth.xml
Outdated
Show resolved
Hide resolved
Build failed due to one of the flaky test cases as test passing when ran again.
The error message that we are getting
solr/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java Lines 462 to 483 in 033be0f
I will try to see If i can get more details on this. Should I open a Jira ticket for this? One observation: solr/solr/core/src/test/org/apache/solr/search/TestCoordinatorRole.java Lines 187 to 200 in 033be0f
|
I looked at the test history -- seems flaky. I found a JIRA issue where you can relay these comments. Looking forward to the lingering small matters being addressed so we can get this merged! |
solr/core/src/test/org/apache/solr/handler/TestUserManagedReplicationWithAuth.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just maybe one little change needed to move a getter and I think it's done
solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
Outdated
Show resolved
Hide resolved
solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientTest.java
Show resolved
Hide resolved
Thinking out loud! The new logic, however bit ugly it is because it gives freedom to manipulate the Is there any way to avoid recreating the Http2SolrClient?The default |
The most important part of Http2SolrClient to be re-used (instead of re-created) is Jetty's HttpClient. Creating another Http2SolrClient that uses an existing HttpClient isn't too bad but yeah it'd be nice if we didn't have to re-create one. This PR is an improvement! IndexFetcher.getLatestVersion, fetchFileList, getStream, and getDetails not only re-use the underlying HttpClient, as before, but now use the SolrClient wrapper, which is more succinct & simple in so doing. Some thoughts on the commit message summarizing this long one:
It's unclear if there was any change with respect to gzip / "useExternalCompression" -- this part of the diff is confusing. |
Unless I hear to the contrary, I'll commit this tonight like midnight EST. Just "main" for a bit. The CHANGES.txt is currently:
That will be more meaningful to users. CHANGES.txt needs to speak to users. |
for the pwd encode format, there missed a ')', which is confusing.
…pache#2395) The URPF, `NumFieldLimitingUpdateRequestProcessorFactory`, blocks all update requests that go through `processAdd` if the core exceeds a configurable threshold of fields. The factory accepts two parameters: `maxFields` is a required integer representing the maximum field threshold, and `warnOnly` is an optional boolean that (when enabled) has the URP chain log warnings instead of blocking updates. The factory is included in the default configset, with warnOnly=false and maxFields=1000. (More lenient settings will be used on branch_9x) --------- Co-authored-by: David Smiley <[email protected]>
UpdateShardHandler * switch "recoveryOnlyHttpClient" to Http2SolrClient RecoveryStrategy: * Use Http2SolrClient * Simplify cancelation of prep recovery command IndexFetcher: * Use Http2SolrClient * Ensure the entire stream is consumed to avoid a connection reset Http2SolrClient: * make HttpListenerFactory configurable (used for internal purposes) --------- Co-authored-by: iamsanjay <[email protected]> Co-authored-by: David Smiley <[email protected]> (cherry picked from commit e62cb1b) fix buildUrl
https://issues.apache.org/jira/browse/SOLR-16505
Switch UpdateShardHandler.getRecoveryOnlyHttpClient to Jetty HTTP2
In
UpdateShardHandler.java
removed the old reference to Apache HTTP client for recoveryUpdate, and initialized with Jetty HTTP client. The recovery client is only used byRecoveryStrategy.java
to recreate the builder with the existing HTTPClient.In
RecoveryStrategy.java
, sendPrepRecoveryCmd sending async request using HttpUriRequest, After replacing it with newer client there is no option to create HttpUriRequest. However, we can send asyncRequest using executor. Upon calling,withExecutor()
to set the executor, it did not work. Further inspection revealed that Http2SolrClient only set executor when they creating new HttpClient, In case, if builder is initialized with existing client there is no way to set the executor. I added the new code to tackle that issue. But now we have two different executor: one for Http2SolrClient and another one for HttpClient.Tests
Added stressRecoveryTest.
Checklist
Please review the following and check all that apply:
main
branch../gradlew check
.