-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Make copies of thread local MessageMetadata when it might be shared #14556
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
Changes from all commits
fa0b2d3
f08626e
a7ebef2
aeee29e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,12 +25,23 @@ | |
| @Data | ||
| public class FilterContext { | ||
| private Subscription subscription; | ||
| private MessageMetadata msgMetadata; | ||
| private final MessageMetadata msgMetadata = new MessageMetadata(); | ||
|
|
||
| public FilterContext() { | ||
| } | ||
|
|
||
| public void reset() { | ||
| subscription = null; | ||
| msgMetadata = null; | ||
| msgMetadata.clear(); | ||
| } | ||
|
|
||
| public static final FilterContext FILTER_CONTEXT_DISABLED = new FilterContext(); | ||
|
|
||
| public MessageMetadata getMsgMetadata() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may be problematic because the filter may want to hold a reference to this object (I don't know why but you know users sometimes do silly things)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please elaborate about the problem. What do you suggest as a solution? |
||
| return this.msgMetadata; | ||
| } | ||
|
|
||
| public void setMsgMetadata(MessageMetadata msgMetadata) { | ||
| this.msgMetadata.clear().copyFrom(msgMetadata); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,7 +45,7 @@ protected MessagePayloadContextImpl newObject(Handle<MessagePayloadContextImpl> | |
|
|
||
| private final Recycler.Handle<MessagePayloadContextImpl> recyclerHandle; | ||
| private BrokerEntryMetadata brokerEntryMetadata; | ||
| private MessageMetadata messageMetadata; | ||
| private final MessageMetadata messageMetadata = new MessageMetadata(); | ||
| private SingleMessageMetadata singleMessageMetadata; | ||
| private MessageIdImpl messageId; | ||
| private ConsumerImpl<?> consumer; | ||
|
|
@@ -68,7 +68,7 @@ public static MessagePayloadContextImpl get(final BrokerEntryMetadata brokerEntr | |
| final MessagePayloadContextImpl context = RECYCLER.get(); | ||
| context.consumerEpoch = consumerEpoch; | ||
| context.brokerEntryMetadata = brokerEntryMetadata; | ||
| context.messageMetadata = messageMetadata; | ||
| context.messageMetadata.copyFrom(messageMetadata); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This may be problematic because the filter may want to hold a reference to this object (I don't know why but you know users sometimes do silly things) |
||
| context.singleMessageMetadata = new SingleMessageMetadata(); | ||
| context.messageId = messageId; | ||
| context.consumer = consumer; | ||
|
|
@@ -82,7 +82,7 @@ public static MessagePayloadContextImpl get(final BrokerEntryMetadata brokerEntr | |
|
|
||
| public void recycle() { | ||
| brokerEntryMetadata = null; | ||
| messageMetadata = null; | ||
| messageMetadata.clear(); | ||
| singleMessageMetadata = null; | ||
| messageId = null; | ||
| consumer = null; | ||
|
|
||
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.
Looks like we will not share
msgMetadatato other threads? I have checked where used themsgMetadata, they should run in the same thread. Maybe I missed something.It's a good motivation, is it better to avoid passing the
msgMetadata? Instead, we can create local variable, looks likeThere 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.
yes, avoiding the instance is a better choice. I'll take a look in the refactoring.
Uh oh!
There was an error while loading. Please reload this page.
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 took a look in the possible refactoring. there's a number of fields that are used from MessageMetadata, so it would turn out to be an ugly solution.
It's possible that a copy isn't necessary in this case, but it's hard to tell without checking all accesses. That's why a "defensive copy" is reasonable.
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.
Ok, looks like we should try our best to avoid passing the MessageMetadata to another method, If we have to pass it to another method, we should make a copy.
For example
pulsar/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/persistent/PersistentDispatcherMultipleConsumers.java
Line 854 in 7cbd849
Use deliverAtTime is enough.
Uh oh!
There was an error while loading. Please reload this page.
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 guess that would be one way to define a rule when to make a copy. (btw. I wonder if it's intentional that the generated copyFrom code doesn't call "clear" as the first step internally. )