-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[refactor][broker] Remove EntryWrapper usages and use MessageMetadata instead #15967
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
[refactor][broker] Remove EntryWrapper usages and use MessageMetadata instead #15967
Conversation
… instead ### Motivation apache#7266 introduced the `EntryWrapper` to store the `Entry` object and the associated `MessageMetadata` if it exists. However, the `getEntry` field of `EntryWrapper` is never used. There is no need to allocate memory for `EntryWrapper`, even if it's allocated from the recycler pool. ### Modifications - Calculate the remaining messages without creating `EntryWrapper` object, just iterate over the parsed message metadata list. - Pass an optional `MessageMetadata` array to `filterEntriesForConsumer` and add the JavaDocs for these two parameters. After that, Remove unused `EntryWrapper` and `updateEntryWrapperWithMetadata`. This PR uses functional programming style to make code more simple and clear. ### Verifying this change - [ ] Make sure that the change passes the CI checks. This change is already covered by existing tests, such as `testBatchMessageDispatchingAccordingToPermits`. ### Documentation Check the box below or label this PR directly. Need to update docs? - [ ] `doc-required` (Your PR needs to update docs and you will update later) - [x] `doc-not-needed` (Please explain why) - [ ] `doc` (Your PR contains doc changes) - [ ] `doc-complete` (Docs have been already added)
|
@BewareMyPower @codelipenghui please give time for other reviewers to see such important patches. I believe that for non trivial patches we must at least give 1 day for people to see what's going on. |
|
@eolivelli Yes, agree. |
|
Sorry for the quick merge since this is a part of my development that I want to split it into multiple PRs. @eolivelli And unfortunately, just now I found this PR introduced a bug that I will fix it soon. |
|
After digging for a while, this PR didn't introduce a bug but it changed the original behavior a little and could bring unexpected behavior. I'll open a new PR and explain it in detail. |
…peekMessageMetadata` ### Motivation apache#15967 removed the `EntryWrapper`, which holds an `Entry` instance that is never used. Instead, after the refactoring, the `MessageMetadata` array is useless, see https://github.com/apache/pulsar/blob/298a573295f845e46f8a55cee366b6db63e997c2/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java#L517-L519 Each `MessageMetadata` instance in the array is returned by `peekMessageMetadata`, whose returned value references a thread local object `Commands#LOCAL_MESSAGE_METADATA`. It brings a problem that if multiple entries were read, all `MessageMetadata` elements in the array reference the same object. However, accidentally, the wrong invocation of `Optional#orElse` saves it. See https://github.com/apache/pulsar/blob/298a573295f845e46f8a55cee366b6db63e997c2/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractBaseDispatcher.java#L133-L134 Each time `peekMessageMetadata` is called, the thread local message metadata will be updated. Unlike `orElseGet`, the expression in `orElse` is always called no matter if the optional is empty. This behavior change increases the invocations count of `peekMessageMetadata` and the `metadataArray` cache became redundant. ### Modifications - Use `orElseGet` instead of `orElse` in `AbstractBaseDispatcher`. - Add a new static method `Commands#peekAndCopyMessageMetadata` that returns a `MessageMetadata` instance allocated from heap memory. - Call `peekAndCopyMessageMetadata` to cache all message metadata instances in `PersistentDispatcherMultipleConsumers`. ### Verifying this change - [ ] Make sure that the change passes the CI checks. It's hard to add tests. As I've explained before, apache#15967 only degrades the performance and doesn't affect the correctness. ### Documentation Check the box below or label this PR directly. Need to update docs? - [ ] `doc-required` (Your PR needs to update docs and you will update later) - [x] `doc-not-needed` (Please explain why) - [ ] `doc` (Your PR contains doc changes) - [ ] `doc-complete`
…peekMessageMetadata` (#15983) ### Motivation #15967 removed the `EntryWrapper`, which holds an `Entry` instance that is never used. Instead, after the refactoring, the `MessageMetadata` array is useless, see https://github.com/apache/pulsar/blob/298a573295f845e46f8a55cee366b6db63e997c2/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java#L517-L519 Each `MessageMetadata` instance in the array is returned by `peekMessageMetadata`, whose returned value references a thread local object `Commands#LOCAL_MESSAGE_METADATA`. It brings a problem that if multiple entries were read, all `MessageMetadata` elements in the array reference the same object. However, accidentally, the wrong invocation of `Optional#orElse` saves it. See https://github.com/apache/pulsar/blob/298a573295f845e46f8a55cee366b6db63e997c2/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractBaseDispatcher.java#L133-L134 Each time `peekMessageMetadata` is called, the thread local message metadata will be updated. Unlike `orElseGet`, the expression in `orElse` is always called no matter if the optional is empty. This behavior change increases the invocations count of `peekMessageMetadata` and the `metadataArray` cache became redundant. ### Modifications - Use `orElseGet` instead of `orElse` in `AbstractBaseDispatcher`. - Add a new static method `Commands#peekAndCopyMessageMetadata` that returns a `MessageMetadata` instance allocated from heap memory. - Call `peekAndCopyMessageMetadata` to cache all message metadata instances in `PersistentDispatcherMultipleConsumers`. ### Verifying this change It's hard to add tests. As I've explained before, #15967 only degrades the performance and doesn't affect the correctness.
… instead (apache#15967) apache#7266 introduced the `EntryWrapper` to store the `Entry` object and the associated `MessageMetadata` if it exists. However, the `getEntry` field of `EntryWrapper` is never used. There is no need to allocate memory for `EntryWrapper`, even if it's allocated from the recycler pool. - Calculate the remaining messages without creating `EntryWrapper` object, just iterate over the parsed message metadata list. - Pass an optional `MessageMetadata` array to `filterEntriesForConsumer` and add the JavaDocs for these two parameters. After that, Remove unused `EntryWrapper` and `updateEntryWrapperWithMetadata`. This PR uses functional programming style to make code more simple and clear. (cherry picked from commit c33b12d)
…peekMessageMetadata` (apache#15983) apache#15967 removed the `EntryWrapper`, which holds an `Entry` instance that is never used. Instead, after the refactoring, the `MessageMetadata` array is useless, see https://github.com/apache/pulsar/blob/298a573295f845e46f8a55cee366b6db63e997c2/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java#L517-L519 Each `MessageMetadata` instance in the array is returned by `peekMessageMetadata`, whose returned value references a thread local object `Commands#LOCAL_MESSAGE_METADATA`. It brings a problem that if multiple entries were read, all `MessageMetadata` elements in the array reference the same object. However, accidentally, the wrong invocation of `Optional#orElse` saves it. See https://github.com/apache/pulsar/blob/298a573295f845e46f8a55cee366b6db63e997c2/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractBaseDispatcher.java#L133-L134 Each time `peekMessageMetadata` is called, the thread local message metadata will be updated. Unlike `orElseGet`, the expression in `orElse` is always called no matter if the optional is empty. This behavior change increases the invocations count of `peekMessageMetadata` and the `metadataArray` cache became redundant. - Use `orElseGet` instead of `orElse` in `AbstractBaseDispatcher`. - Add a new static method `Commands#peekAndCopyMessageMetadata` that returns a `MessageMetadata` instance allocated from heap memory. - Call `peekAndCopyMessageMetadata` to cache all message metadata instances in `PersistentDispatcherMultipleConsumers`. It's hard to add tests. As I've explained before, apache#15967 only degrades the performance and doesn't affect the correctness. (cherry picked from commit 36690f5)
… instead (apache#15967) apache#7266 introduced the `EntryWrapper` to store the `Entry` object and the associated `MessageMetadata` if it exists. However, the `getEntry` field of `EntryWrapper` is never used. There is no need to allocate memory for `EntryWrapper`, even if it's allocated from the recycler pool. - Calculate the remaining messages without creating `EntryWrapper` object, just iterate over the parsed message metadata list. - Pass an optional `MessageMetadata` array to `filterEntriesForConsumer` and add the JavaDocs for these two parameters. After that, Remove unused `EntryWrapper` and `updateEntryWrapperWithMetadata`. This PR uses functional programming style to make code more simple and clear. (cherry picked from commit c33b12d)
…peekMessageMetadata` (apache#15983) apache#15967 removed the `EntryWrapper`, which holds an `Entry` instance that is never used. Instead, after the refactoring, the `MessageMetadata` array is useless, see https://github.com/apache/pulsar/blob/298a573295f845e46f8a55cee366b6db63e997c2/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java#L517-L519 Each `MessageMetadata` instance in the array is returned by `peekMessageMetadata`, whose returned value references a thread local object `Commands#LOCAL_MESSAGE_METADATA`. It brings a problem that if multiple entries were read, all `MessageMetadata` elements in the array reference the same object. However, accidentally, the wrong invocation of `Optional#orElse` saves it. See https://github.com/apache/pulsar/blob/298a573295f845e46f8a55cee366b6db63e997c2/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/AbstractBaseDispatcher.java#L133-L134 Each time `peekMessageMetadata` is called, the thread local message metadata will be updated. Unlike `orElseGet`, the expression in `orElse` is always called no matter if the optional is empty. This behavior change increases the invocations count of `peekMessageMetadata` and the `metadataArray` cache became redundant. - Use `orElseGet` instead of `orElse` in `AbstractBaseDispatcher`. - Add a new static method `Commands#peekAndCopyMessageMetadata` that returns a `MessageMetadata` instance allocated from heap memory. - Call `peekAndCopyMessageMetadata` to cache all message metadata instances in `PersistentDispatcherMultipleConsumers`. It's hard to add tests. As I've explained before, apache#15967 only degrades the performance and doesn't affect the correctness. (cherry picked from commit 36690f5)
Motivation
#7266 introduced the
EntryWrapperto store the
Entryobject and the associatedMessageMetadataif itexists. However, the
getEntryfield ofEntryWrapperis never used.There is no need to allocate memory for
EntryWrapper, even if it'sallocated from the recycler pool.
Modifications
EntryWrapperobject, just iterate over the parsed message metadata list.
MessageMetadataarray tofilterEntriesForConsumerand add the JavaDocs for these two parameters.
After that, Remove unused
EntryWrapperandupdateEntryWrapperWithMetadata.This PR uses functional programming style to make code more simple and clear.
Verifying this change
This change is already covered by existing tests, such as
testBatchMessageDispatchingAccordingToPermits.Documentation
Check the box below or label this PR directly.
Need to update docs?
doc-required(Your PR needs to update docs and you will update later)
doc-not-needed(Please explain why)
doc(Your PR contains doc changes)
doc-complete(Docs have been already added)