Skip to content
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-17516: LBHttpSolrClient: support HttpJdkSolrClient (Generic Version) #2828

Merged
merged 26 commits into from
Nov 19, 2024

Conversation

jdyer1
Copy link
Contributor

@jdyer1 jdyer1 commented Oct 31, 2024

Similar to #2805, this is a minimal PR to add Load Balancing functionality for HttpJdkSolrClient. Included is test refactoring, adding the *JdkClient as a random choice for the integration test.

Whereas #2805 created a class hierarchy, this makes LBHttp2SolrClient generic. Adding a generic parameter to this class will not break backwards-compatibility. This seems a better option that #2805.

One downside is we retain the name LBHttp2SolrClient although it is no longer strictly to be used with Http2SolrClient. However, the legacy implementation already uses the preferred name: LBHttpSolrClient. Whenever the legacy implementation is removed, I recommend also renaming LBHttp2SolrClient to LBHttpSolrClient.

Copy link
Contributor

@dsmiley dsmiley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I like it! Better than the subclass one. I concur with your rename proposals.

@@ -173,8 +173,8 @@ public NamedList<Object> request(SolrRequest<?> solrRequest, String collection)
"Timeout occurred while waiting response from server at: " + pReq.url, e);
} catch (SolrException se) {
throw se;
} catch (RuntimeException re) {
throw new SolrServerException(re);
} catch (IOException | RuntimeException e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The request method declares it throws IOException; shouldn't we propagate it instead of wrap?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found that LBHttpSolrClient needs a SolrServerException to detect a down node. Yet we still can throw an IOException here during prepareRequest. This roughly mimics the exception handling in Http2SolrClient.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay; just needs a comment because it looks wrong

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, maybe LBHttpSolrClient should be enhanced to catch the IOException to behave properly here? Otherwise, it seems wrong just looking at this SolrClient to throw/not-throw based on some wrapping/delegating client unless we spell out these things in the documented semantics of this method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, the doc-comment on the LBSolrClient request method says,

If a request fails due to an IOException, the server is moved to the dead pool

So I restored the previous behavior in HttpJdkSolrClient and made the modification in LBSolrClient. This new behavior is covered by LBHttp2SolrClientIntegrationTest.

private long aliveCheckIntervalMillis =
TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS); // 1 minute between checks
protected String defaultCollection;

public Builder(Http2SolrClient http2Client, Endpoint... endpoints) {
this.http2SolrClient = http2Client;
public Builder(C http2Client, LBSolrClient.Endpoint... endpoints) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a static import for that Endpoint inner class so it looks simple as it was?

minor but can you please rename "http2Client" to incorporate the name "Solr" like just call it "solrClient" is fine. I like a SolrClient and HttpClient to not be confusable.

Comment on lines 53 to 54
try (Http2SolrClient http2SolrClient =
new Http2SolrClient.Builder(url).withTheseParamNamesInTheUrl(urlParamNames).build();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps some tests methods shouldn't care in theory what the httpSolrClient impl is exactly but it'd be nice to get one randomly or via parameterization even better. Not sure if that'd be too difficult.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, 4/5 test methods here are using a mock client. The withTheseParamNamesInTheUrl case is being tested with the clients' own unit tests. I did add a random choice to LBHttp2SolrClientIntegrationTest (renamed). I think this is pretty good coverage already.

* Taken from: https://www.baeldung.com/java-httpclient-ssl sec 4.1, 2024/02/12. This is an
* all-trusting Trust Manager. Works with self-signed certificates.
*/
public class MockTrustManager extends X509ExtendedTrustManager {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice to see this separated

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for taking the time to review. I'll plan to commit this (main only?; 9.8?) early next week.

Improve method signature hygene
…erverException

- HttpJdkSolrClient to throw IOException (restore existing behavior)
Comment on lines -702 to +704
if (justFailed == null) justFailed = new HashMap<>();
if (justFailed == null) {
justFailed = new HashMap<>();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a shame to see duplication in getRootCause IOException detection with the dedicated clause. Maybe it'd be cleaner to have another try-catch just around calling request() above that detects the IOException and throws it? Just a thought; I leave it to you.

@jdyer1
Copy link
Contributor Author

jdyer1 commented Nov 15, 2024

@gerlowskija @dsmiley This PR required significant changes to merge with the incoming changes from SOLR-17256. I would appreciate another round of review before merging.

Copy link
Contributor

@dsmiley dsmiley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, though I didn't look too carefully.

});
return future;
} catch (SolrServerException | IOException e) {
// Unreachable, since 'requestWithBaseUrl' above is running the request asynchronously
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an "assert false" would be helpful.
I suppose a requestAsyncWithBaseUrl would be nice but not a big deal.

@jdyer1 jdyer1 merged commit 72cc275 into apache:main Nov 19, 2024
3 of 4 checks passed
@jdyer1 jdyer1 deleted the feature/SOLR-17516-c branch November 19, 2024 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants