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-17535: Migrate ClusterState.getCollectionsMap callers to Stream #2846

Merged
merged 14 commits into from
Nov 13, 2024

Conversation

dsmiley
Copy link
Contributor

@dsmiley dsmiley commented Nov 5, 2024

https://issues.apache.org/jira/browse/SOLR-17535

This PR builds on top of the previous PR #2834 , you can ignore changes here for that (the first set of commits on this PR) as that's reviewed separately.

Copy link
Member

@murblanc murblanc left a comment

Choose a reason for hiding this comment

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

Left a few comments, looks good!

.getClusterState()
.collectionStream()
.map(DocCollection::getConfigName)
.anyMatch(cf -> cf.equals(configSetName));
Copy link
Member

Choose a reason for hiding this comment

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

Maybe do equals() in the other direction to prevent NPE if cf is null?

.filter(entry -> !entry.isPerReplicaState())
.map(
docCollection ->
computeCollectionUpdate(nodeName, docCollection.getName(), docCollection, zkClient))
Copy link
Member

Choose a reason for hiding this comment

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

Maybe change the signature of computeCollectionUpdate() to get the name from the passed in DocCollection and save one argument here?

if (collection == null) {
collectionsMap = clusterState.getCollectionsMap();
Stream<DocCollection> collectionStream;
if (collection == null) { // uh-oh; hopefully not a lot
Copy link
Member

Choose a reason for hiding this comment

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

I assume you mean that cluster status is going to return a lot of data and we don't like it, but the comment doesn't really help to understand that (and if that's the actual need, it's not an issue, just a price to pay...)

Copy link
Member

Choose a reason for hiding this comment

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

Unrelated, but this method that was already hard to read and I find the changes below make it even harder to read/maintain.
Maybe it's just me though.

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 made some slight changes that maybe helps readability more. I didn't find it straight-forward previously.

.collectionStream()
.map(DocCollection::getActiveSlicesArr)
.filter(Objects::nonNull)
.forEach(them -> Collections.addAll(slices, them));
Copy link
Member

Choose a reason for hiding this comment

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

maybe use another variable name than them that doesn't convey much meaning?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

slices would be logical but that's already in-scope; it's an "out" argument. Despite the scope creep, I refactored further to eliminate the argument. I think it's overall clearer.

@@ -1067,6 +1068,10 @@ public void testDeleteAliasedCollection() throws Exception {
});
}

private static String toString(ClusterState state) {
Copy link
Member

Choose a reason for hiding this comment

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

I'd name this collectionNames or something with more meaning than toString

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure. BTW it's purely used for printing on an assert failure.

}

return success;
return ClusterStateUtil.waitFor(
Copy link
Member

Choose a reason for hiding this comment

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

Nice cleanup!

*/
@Deprecated
Copy link
Member

Choose a reason for hiding this comment

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

Are there still uses of getCollectionsMap() in the code? If not, I suggest to remove this method rather than deprecate it. This is not a public API, right?
If references remain, why not remove them?
Same comment for getCollectionStates() below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are public and are surely called by our users (and our users internally :sad:). On a subsequent PR that will only occur on main (10x), I will remove them. I will also remove them in our fork.


/**
* Calls {@code consumer} with a resolved {@link DocCollection}s for all collections. Use this
* sparingly in case there are many collections.
*/
public void forEachCollection(Consumer<DocCollection> consumer) {
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we should keep this method now that we have collectionStream().

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 agree 100% to remove this as well; I forgot to raise this point and I held myself back from scope creep in doing so in this PR. I'll do a fast followup for that little change; same JIRA issue.

throw new SolrException(ErrorCode.SERVER_ERROR, "Interrupted");
final long timeoutAtNs =
System.nanoTime() + TimeUnit.NANOSECONDS.convert(timeoutMs, TimeUnit.MILLISECONDS);
while (System.nanoTime() < timeoutAtNs) {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe change into a do...while so that:

  • It runs at least once even if timeoutMs is 0 (or non 0 + an improbable GC at the wrong moment)
  • It doesn't sleep then fails directly without checking again if predicate matches when the timeout is exceeded

@@ -168,7 +168,7 @@ public void call(ClusterState state, ZkNodeProps message, NamedList<Object> resu
}

// delete related config set iff: it is auto generated AND not related to any other collection
String configSetName = coll.getConfigName();
String configSetName = coll == null ? null : coll.getConfigName();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

IntelliJ helpfully pointed out an issue nearby this PR with a trivial fix. Basically, it might not have been possible to delete a non-existent collection but now it might be. (couldn't find a test for this)

Comment on lines -1118 to +1113
List<Slice> activeSlices = new ArrayList<>();
List<Slice> activeSlices;
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 really liked this little improvement to this method clarify that we produce the activeSlices once; it's not built up / amended to a growing list (which wasn't super obvious)

* has an alternative implementation if {@code collection} is null, in which the predicate must
* match *all* collections. Returns whether the predicate matches or not in the allotted time;
* does *NOT* throw {@link TimeoutException}.
*/
public static boolean waitFor(
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 aligned the parameters to be closer to that of ZkStateReader.waitForState

@dsmiley dsmiley merged commit 24fe191 into apache:main Nov 13, 2024
5 checks passed
@dsmiley dsmiley deleted the clusterStatesNoGetCollectionsMapCallers branch November 13, 2024 22:28
dsmiley added a commit that referenced this pull request Nov 19, 2024
…2846)

Deprecated getCollectionsMap.

A refactoring, albeit some additional points:
* DeleteCollection: avoid NPE for non-existent collection (trivial change)
* ClusterStateUtil (test-framework): optimize waiting to use ZkStateReader.waitForState for single-collection

(cherry picked from commit 24fe191)
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