-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
[fix][broker] Execute the pending callbacks in order before ready for incoming requests #23266
[fix][broker] Execute the pending callbacks in order before ready for incoming requests #23266
Conversation
… incoming requests
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 catch. I think we also have other pulsar logics, e.g. FutureUtil.sequencer that uses future chain for ordering. I wonder if we need to revisit that too.
pulsar-broker/src/main/java/org/apache/pulsar/broker/PulsarService.java
Outdated
Show resolved
Hide resolved
Yes, nice catch @BewareMyPower. It's useful to consider replacing FutureUtil.sequencer usage with |
Actually, I see that the sequencer uses thenCompose, which I think the order should be fifo. |
I think it's different. pulsar/pulsar-common/src/main/java/org/apache/pulsar/common/util/FutureUtil.java Lines 234 to 242 in 9626e7e
the instances are chained and .thenCompose isn't called multiple times for the same instance.
|
The sequencer is different because it's a chained futures (like linked list) that each future has only 1 callback in its internal stack while the existing design is a single future with N callbacks. However, the sequencer might be unnecessarily complicated for this simple case so I won't adopt it. |
I found a deadlock in |
Good work @BewareMyPower ! |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #23266 +/- ##
============================================
+ Coverage 73.57% 74.55% +0.97%
- Complexity 32624 33779 +1155
============================================
Files 1877 1926 +49
Lines 139502 145056 +5554
Branches 15299 15864 +565
============================================
+ Hits 102638 108141 +5503
+ Misses 28908 28646 -262
- Partials 7956 8269 +313
Flags with carried forward coverage won't be shown. Click here to find out more.
|
… incoming requests (apache#23266) (cherry picked from commit ca0fb44) (cherry picked from commit ca8d724)
… incoming requests (apache#23266)
… incoming requests (apache#23266) (cherry picked from commit ca0fb44) (cherry picked from commit ca8d724)
Background Knowledge
CompletableFuture has an intuitive behavior
The outputs of the code above are:
That's because it maintains callbacks in the LIFO stack, not FIFO queue.
Motivation
#22977 breaks the order of some events during extensible load manager's start by adding the runnable objects via
thenRun()
. The previous events order ofExtensibleLoadManagerImpl
:playLeader()
orplayFollower()
serviceUnitStateChannel.start()
brokerLoadDataReportTask
,topBundlesLoadDataReportTask
, etc.) and setstarted
with true.Now, since they will be executed in reverse order,
started
will first be set true and then event 1 and 2 happened. It might cause unexpected issuesModifications
Add a synchronized list to queue the pending tasks and execute them in order before the future is complete.
Documentation
doc
doc-required
doc-not-needed
doc-complete
Matching PR in forked repository
PR in forked repository: