[ https://issues.apache.org/jira/browse/SOLR-8323?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15264743#comment-15264743 ]
ASF GitHub Bot commented on SOLR-8323: -------------------------------------- Github user dragonsinth commented on a diff in the pull request: https://github.com/apache/lucene-solr/pull/32#discussion_r61644721 --- Diff: solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java --- @@ -491,19 +493,28 @@ private void refreshLegacyClusterState(Watcher watcher) final Stat stat = new Stat(); final byte[] data = zkClient.getData(CLUSTER_STATE, watcher, stat, true); final ClusterState loadedData = ClusterState.load(stat.getVersion(), data, emptySet(), CLUSTER_STATE); + final Set<String> liveNodes = new HashSet<>(this.liveNodes); synchronized (getUpdateLock()) { if (this.legacyClusterStateVersion >= stat.getVersion()) { // Nothing to do, someone else updated same or newer. return; } - this.legacyCollectionStates = loadedData.getCollectionStates(); - this.legacyClusterStateVersion = stat.getVersion(); - for (Map.Entry<String, ClusterState.CollectionRef> entry : this.legacyCollectionStates.entrySet()) { - if (entry.getValue().isLazilyLoaded() == false) { - // a watched collection - trigger notifications - notifyStateWatchers(entry.getKey(), entry.getValue().get()); + LOG.info("Updating legacy cluster state - {} entries in legacyCollectionStates", legacyCollectionStates.size()); + for (Map.Entry<String, CollectionWatch> watchEntry : this.collectionWatches.entrySet()) { + String coll = watchEntry.getKey(); + CollectionWatch collWatch = watchEntry.getValue(); + ClusterState.CollectionRef ref = this.legacyCollectionStates.get(coll); + if (ref == null) + continue; + // watched collection, so this will always be local + DocCollection newState = ref.get(); + if (!collWatch.stateWatchers.isEmpty() + && !Objects.equals(loadedData.getCollectionStates().get(coll).get(), newState)) { + notifyStateWatchers(liveNodes, coll, newState); --- End diff -- I just realized you don't want to call user code while holding the update lock. I think you're going to need to move this out of the synchronized block. In fact.... this is really nasty now that I think about it. In general, you're going to want to defer calling any user code until the current constuctState() operation finishes. Otherwise, the user code is potentially going to see a stale copy of the state that you haven't finished updating yet. I think we're going to have to build a queue of outstanding state watchers to notify and always call them later, probably in an executor. I know that sounds like a bit of work, but I'm not sure I can see how it would be safe otherwise. @markrmiller any thoughts? > Add CollectionWatcher API to ZkStateReader > ------------------------------------------ > > Key: SOLR-8323 > URL: https://issues.apache.org/jira/browse/SOLR-8323 > Project: Solr > Issue Type: Improvement > Affects Versions: master > Reporter: Alan Woodward > Assignee: Alan Woodward > Attachments: SOLR-8323.patch, SOLR-8323.patch, SOLR-8323.patch, > SOLR-8323.patch > > > An API to watch for changes to collection state would be a generally useful > thing, both internally and for client use. -- This message was sent by Atlassian JIRA (v6.3.4#6332) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@lucene.apache.org For additional commands, e-mail: dev-h...@lucene.apache.org