-
Notifications
You must be signed in to change notification settings - Fork 671
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
SOLR-17535: Migrate ClusterState.getCollectionsMap callers to Stream #2846
Conversation
Deprecated the latter.
Overhaul ClusterStateUtil; optimize for when one collection is specified by calling ZkStateReader.waitForState.
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.
Left a few comments, looks good!
.getClusterState() | ||
.collectionStream() | ||
.map(DocCollection::getConfigName) | ||
.anyMatch(cf -> cf.equals(configSetName)); |
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.
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)) |
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.
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 |
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 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...)
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.
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.
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 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)); |
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.
maybe use another variable name than them
that doesn't convey much meaning?
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.
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) { |
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'd name this collectionNames
or something with more meaning than toString
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.
Sure. BTW it's purely used for printing on an assert failure.
} | ||
|
||
return success; | ||
return ClusterStateUtil.waitFor( |
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.
Nice cleanup!
*/ | ||
@Deprecated |
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.
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.
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.
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) { |
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 wonder if we should keep this method now that we have collectionStream()
.
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 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) { |
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.
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 ifpredicate
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(); |
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.
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)
List<Slice> activeSlices = new ArrayList<>(); | ||
List<Slice> activeSlices; |
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 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( |
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 aligned the parameters to be closer to that of ZkStateReader.waitForState
…allers # Conflicts: # solr/CHANGES.txt # solr/solrj/src/java/org/apache/solr/common/cloud/ClusterState.java
…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)
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.