Conversation
jiajunwang
left a comment
There was a problem hiding this comment.
I see you have 2 similar PRs. And I think we are all reviewing the other one. Could you please specify which one is the right PR to review?
And you might need to refer to the comments there for this PR's change, unfortunately.
helix-core/src/main/java/org/apache/helix/messaging/DefaultMessagingService.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
Outdated
Show resolved
Hide resolved
|
@jiajunwang 14 hours ago Contributor Put this logic in the executor does not make sense to me. |
|
@jiajunwang Sorry if it's confusing. This PR is for the periodic refresh. I have copied and pasted all your comments here and I will address them here. |
helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
Outdated
Show resolved
Hide resolved
helix-common/src/main/java/org/apache/helix/SystemPropertyKeys.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/messaging/DefaultMessagingService.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
Outdated
Show resolved
Hide resolved
helix-core/src/test/java/org/apache/helix/messaging/handling/TestPerioidicMessageRefresh.java
Outdated
Show resolved
Hide resolved
helix-core/src/test/java/org/apache/helix/messaging/handling/TestPerioidicMessageRefresh.java
Outdated
Show resolved
Hide resolved
helix-core/src/test/java/org/apache/helix/messaging/handling/TestPerioidicMessageRefresh.java
Outdated
Show resolved
Hide resolved
helix-core/src/test/java/org/apache/helix/messaging/handling/TestPerioidicMessageRefresh.java
Outdated
Show resolved
Hide resolved
helix-core/src/test/java/org/apache/helix/messaging/handling/TestPerioidicMessageRefresh.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
Outdated
Show resolved
Hide resolved
helix-core/src/test/java/org/apache/helix/messaging/handling/TestPerioidicMessageRefresh.java
Outdated
Show resolved
Hide resolved
helix-core/src/test/java/org/apache/helix/messaging/handling/TestPerioidicMessageRefresh.java
Outdated
Show resolved
Hide resolved
helix-core/src/test/java/org/apache/helix/messaging/handling/TestPerioidicMessageRefresh.java
Outdated
Show resolved
Hide resolved
helix-core/src/test/java/org/apache/helix/messaging/handling/TestPerioidicMessageRefresh.java
Outdated
Show resolved
Hide resolved
helix-core/src/test/java/org/apache/helix/messaging/handling/TestPerioidicMessageRefresh.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/messaging/handling/HelixTaskExecutor.java
Outdated
Show resolved
Hide resolved
d4c167f to
00cb800
Compare
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
|
I just saw this diff. In fact, this is a totally different from what it was before. I have quite some reservation to add periodical refresh in CallbackHandler. CallbackHandler is the interface with zkclient managing the lifecycle of a specific Helix property path. Specifically they handle notification (further calling back to application logic) and registering further notification logic. The part actually already had some notable issues (lose notification, or installing "leaked path etc) that should be addressed. We should not complicate this part with further here. |
Doing periodic refresh in callback handler can actually resolve the issue that you mentioned such as lost notification or missing watcher. This periodic refresh logic is very independent, it's a separate thread, and it put an event in the event queue only if there is no event processed for a while. That being said, it the callback handler is functioning well and events are processed normally, it won't add much burden to the performance since the periodic refresh event won't be generated. |
helix-common/src/main/java/org/apache/helix/SystemPropertyKeys.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
| // so we won't have a memory leakage when we cancel scheduled task | ||
| _periodicRefreshExecutor.setRemoveOnCancelPolicy(true); | ||
| _scheduledRefreshFuture = _periodicRefreshExecutor | ||
| .scheduleWithFixedDelay(new RefreshTask(), _periodicRefreshInterval, |
There was a problem hiding this comment.
I think we talked about at least 2 of the following points:
- If the callback is triggered, the timer should be reset and the wait until the interval passes.
- If the queue is not empty, then we don't need to trigger the refresh.
There was a problem hiding this comment.
They need to be done to avoid unnecessary performance impact.
There was a problem hiding this comment.
@jiajunwang The previous PR contains the first condition you mentioned. I added the second condition in the updated PR. And both checks are still being done in the callback handler instead of ZK event queue.
As per our discussion on Friday, I tried to do this in the ZKEvent queue, and found it hard to do, when an event coming in at the ZKEvent level, we don't know the change type of the event, thus not able to reset the timer accordingly. Currently at the ZKEvent level, no Helix logics are involved so I think it's better we keep it that way.
For your concern on parallel invoke, we synchronize on Helix manager in the invoke method, so it should be fine.
Let's discuss more if you still have concern about this.
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
Outdated
Show resolved
Hide resolved
| /** | ||
| * This class tests that if there are no incoming events, the onMessage method in message listener will be called by message periodic refresh | ||
| */ | ||
| public class TestPeriodicRefresh extends ZkUnitTestBase { |
There was a problem hiding this comment.
@kaisun2000 since you raise this concern, please review this test case and verify if this is enough or not : )
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
|
Thanks for the update. Could you please add more information in the description about what the issue this refresh trying to address? I mean we discussed several scenarios that cannot be addressed by the other fixes, then we decided to proceed to finish this PR. But let's make it clear what is the missing part. |
jiajunwang
left a comment
There was a problem hiding this comment.
"Refresh" to "Trigger" for all the parameters for consistency?
Or we can call it "periodicCallbackInterval"? Then scheduleCallbackFuture, etc.
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
| wait(remainingTime); | ||
| } | ||
| } | ||
| } catch (Exception e) { |
There was a problem hiding this comment.
For the interruption exception, we may want to exit the execution.
There was a problem hiding this comment.
I have made changes to separate the interrupted exception with other exceptions. I will interrupt the thread when interrupted exception is caught, is this what you wanted?
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
| _batchCallbackProcessor.resetEventQueue(); | ||
| if (_scheduledRefreshFuture != null) { | ||
| _periodicRefreshExecutor.shutdownNow(); | ||
| initRefreshTask(); |
There was a problem hiding this comment.
The next event would be FINALIZE, so even the periodic task is triggered, it won't really invoke the handling logic successfully. I think we shall not to init here.
Shall we do it in the init() call?
There was a problem hiding this comment.
I have updated the initTriggerTask() method to include reset as well. Please take a look. Thanks!
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
Outdated
Show resolved
Hide resolved
jiajunwang
left a comment
There was a problem hiding this comment.
Looks good in general. Some minor comments.
Meanwhile, I think we are still discussing the default configuration. Let me approve after that decision has been made.
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
| } | ||
| // When cancelling the task future, it removes the task from the queue | ||
| // so we won't have a memory leakage when we cancel scheduled task | ||
| _periodicTriggerExecutor.setRemoveOnCancelPolicy(true); |
There was a problem hiding this comment.
Shall we only set it once after the fresh construct?
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
| subscribeForChangesAsyn(changeContext.getType(), _path, _watchChild); | ||
| } | ||
|
|
||
| if (_periodicTriggerExecutor != null) { |
There was a problem hiding this comment.
Can we put this in the initTriggerTask() method?
There was a problem hiding this comment.
This is to prevent the update of last invoke time for the cases where periodic trigger is not enabled. I don't think I can move this to init?
There was a problem hiding this comment.
Let's put it to the very beginning of this method?
| * Used to initialize a periodic triggered task | ||
| * Schedule tasks in a task executor with fixed intervals | ||
| */ | ||
| private void initTriggerTask() { |
There was a problem hiding this comment.
nit, take _periodicTriggerInterval as the parameter, and don't refer to the global private field. This is a good style in which you can reduce the impact of a private field in the class. So less dependency if you want to make any further change.
There was a problem hiding this comment.
Great suggestion! Fixed. Thanks!
| _periodicTriggerExecutor.setRemoveOnCancelPolicy(true); | ||
| } | ||
| _scheduledTriggerFuture = _periodicTriggerExecutor | ||
| .scheduleWithFixedDelay(new TriggerTask(), _periodicTriggerInterval, |
There was a problem hiding this comment.
I overlooked this part before. Why do you need to use scheduleWithFixedDelay() here? The TriggerTask object will keep running in the thread, right?
There was a problem hiding this comment.
Discussed offline. A single long running thread is sufficient. Updated.
| try { | ||
| while (true) { | ||
| long currentTime = System.currentTimeMillis(); | ||
| long remainingTime = _lastInvokeTime + _periodicTriggerInterval - currentTime; |
There was a problem hiding this comment.
To reduce the usage of _periodicTriggerInterval in the whole callback class, could you please pass the interval as a constructor parameter? That would be a cleaner design.
helix-core/src/main/java/org/apache/helix/manager/zk/ZKHelixManager.java
Outdated
Show resolved
Hide resolved
| subscribeForChangesAsyn(changeContext.getType(), _path, _watchChild); | ||
| } | ||
|
|
||
| if (_periodicTriggerExecutor != null) { |
There was a problem hiding this comment.
Let's put it to the very beginning of this method?
5d36f68 to
bb9bd30
Compare
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
helix-core/src/main/java/org/apache/helix/manager/zk/CallbackHandler.java
Outdated
Show resolved
Hide resolved
|
Close due to inactive. |
Issues
#996
Description
This PR adds a scheduled periodic task to read leftover messages from zk.
There are several situations that we would need this periodic refresh:
What would not be fixed by this PR is out of order problem, which is another issue may cause missing messages. For example, we may miss an event because its callback comes in after a finalize type event, so it will be ignored. Since this periodic refresh is done through generating an event, this out of order issue may affect refresh events too.
The refresh is done in callback handler and will be triggered if the time has passed for as long as a user defined interval since last processed event. The refresh is achieved by queuing an empty callback type event into the event processor.
Tests
TestPerioidicRefresh
Running
Commits
Documentation (Optional)
(Link the GitHub wiki you added)
Code Quality
(helix-style-intellij.xml if IntelliJ IDE is used)