kaisun2000 commented on a change in pull request #1035:
URL: https://github.com/apache/helix/pull/1035#discussion_r431602293
##########
File path:
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
##########
@@ -752,6 +756,10 @@ public void handleChildChange(String parentPath,
List<String> currentChilds) {
changeContext.setType(NotificationContext.Type.CALLBACK);
changeContext.setPathChanged(parentPath);
changeContext.setChangeType(_changeType);
+ if (!isReady()) {
+ // avoid leaking CallbackHandler
+ return;
+ }
Review comment:
This I thought about it carefully before. This is exactly what we want,
no handling the event in this case.
First, we can reason it this way. "no ready" is either the callbackhandler
is never initialized, or finalized. (Confirmed by examining the code setting
isReady to false). In both cases, the callbackhandler should meet the invariant
that they don't subscribe to changes from Zookeeper, they don't put them onto
ZkClient's data/child listener lists. Thus, they don't handle event and invoke
further callback in the callbackhandler. In fact, they can be trigger-ed only
in the fireAllEvent's lambda. (Long term, we should rethink about fireAllEvent.)
Second, that is what previous developer intended to do also. See the
following code, the previous developer also skip all the rest processing.
```java
public void enqueueTask(NotificationContext changeContext) throws Exception {
// async mode only applicable to CALLBACK from ZK, During INIT and
FINALIZE invoke the
// callback's immediately.
if (_batchModeEnabled && changeContext.getType() ==
NotificationContext.Type.CALLBACK) {
logger.debug("Enqueuing callback");
if (!isReady()) {
logger.info("CallbackHandler is not ready, ignore change callback
from path: " + _path
+ ", for listener: " + _listener);
} else {
synchronized (this) {
if (_batchCallbackProcessor != null) {
_batchCallbackProcessor.queueEvent(changeContext.getType(),
changeContext);
} else {
throw new HelixException(
"Failed to process callback in batch mode. Batch Callback
Processor does not exist.");
}
}
}
} else {
invoke(changeContext);
}
```
Of course, previous batchProcessor or CallbackHandler-AsycSubscribe
singleton have a deadly drawback. They violate the important invariant -- **the
code needs to install the watch before or at the same time when reading the
current snapshot of data upon watch notification in order not to lose update.**
This is the reason batchProcessor or CallbackHandler-AsycSubscribe singleton
lose update. And this is probably also the reason we added line 763 to do
subscribeForChanges() synchronously.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]