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
Issue 16802: fix Repeated messages of shared dispatcher #16812
Issue 16802: fix Repeated messages of shared dispatcher #16812
Conversation
Changes: sendMessagesToConsumer must block reads of new entries otherwise we will end up in reading duplicates
break; | ||
sendInProgress = true; | ||
try { | ||
if (needTrimAckedMessages()) { |
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.
Could you move this try
block to another method to avoid so many code changes? For example,
private void trySendMessagesToConsumers(ReadType readType, List<Entry> entries) {
/* ... */
}
protected synchronized void sendMessagesToConsumers(ReadType readType, List<Entry> entries) {
sendInProgress = true;
try {
trySendMessagesToConsumers(readType, entries);
} finally {
sendInProgress = false;
}
readMoreEntries();
}
In addition, the following code in your original code can be removed because in the finally
block sendInProgress
would be false, then readMoreEntries
will be called after that.
if (entriesToDispatch == 0) {
sendInProgress = false;
readMoreEntries();
return;
}
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.
makes sense
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.
LGTM. Thanks for your quick fix!
|
||
protected synchronized void trySendMessagesToConsumers(ReadType readType, List<Entry> entries) { |
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.
The PersistentStickyKeyDispatcherMultipleConsumers should also override this method.
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.
you are right, thanks for the heads up
I will also add a comment for future people who will put their hands here
@@ -278,7 +278,6 @@ public void testDelayedDeliveryWithMultipleConcurrentReadEntries() | |||
for (int i = 0; i < N; i++) { | |||
msg = consumer.receive(10, TimeUnit.SECONDS); | |||
receivedMsgs.add(msg.getValue()); | |||
consumer.acknowledge(msg); |
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.
Why need to remove this line?
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 added that line in the PR that created this problem.
this line made the test pass,
with this "fix" now the test still passes
this test is very interesting because it runs many readMoreEntries() in a separate thread, simulating the mess that happens inside the broker
it is important to revert this change to the test
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 see.
/pulsarbot rerun-failure-checks |
Please check the failed test
|
@codelipenghui I am looking into the failed test. |
@codelipenghui I have fixed the test, there was a problem in the KEY_SHARED dispatcher |
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 have tried to run some performance test on Shared and Key_Shared subscription. Seems to have no noticeable performance regression
@codelipenghui @BewareMyPower I have merged the PR |
@@ -89,7 +89,7 @@ public class PersistentDispatcherMultipleConsumers extends AbstractDispatcherMul | |||
protected volatile PositionImpl minReplayedPosition = null; | |||
protected boolean shouldRewindBeforeReadingOrReplaying = false; | |||
protected final String name; | |||
|
|||
protected boolean sendInProgress; |
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 think this flag should be volatile
?
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.
Itbis guarded by synchronized blocks. No need to makenit volatile
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 misunderstood something, you're right.
(cherry picked from commit 825b68d)
…sages of shared dispatcher (#16812)
Changes: sendMessagesToConsumer must block reads of new entries otherwise we will end up in reading duplicates
Fixes #16802 #16693
Motivation
As described in #16802 it may happen that multiple calls to
readMoreEntries
are served before the execution ofsendMessagesToConsumer
Unfortunately there is no control over the execution of
readMoreEntries
, it may happen in many different threadpoolsModifications
Add a flag to prevent concurrent execution of
sendMessagesToConsumer
withreadMoreEntries
.Revert aa change to a test modified in #16802 to make the test pass
Verifying this change
This change is already covered by existing tests
doc-not-needed