[fix][broker] Restore PendingAcksMap#get binary compatibility#26180
[fix][broker] Restore PendingAcksMap#get binary compatibility#26180Denovo1998 wants to merge 1 commit into
Conversation
|
Could you clarify the concrete external use case that requires
Restoring it only to preserve a hypothetical call site would add an internal representation, including the |
|
@void-ptr974 I think you are right too. |
@Denovo1998 Similar thoughts as @void-ptr974 expressed in #26180 (comment). It would be great to hear what the use case is. |
|
@lhotari Although MoP uses getPendingAcks().remove(...), which indicates that someone is indeed accessing this internal state, it may not prove that the removed get has an actual use case. So I think it's okay to close this PR. |
Motivation
PR #26030 replaced
PendingAcksMapobject values with packed primitive values and removed the publicPendingAcksMap#get(long, long)method. However, this method was included in previous Pulsar releases, including Pulsar 4.0.x and 4.1.x, and is reachable by broker extensions through the publicConsumer#getPendingAcks()method.A
BrokerInterceptorcompiled against one of those releases can therefore fail withNoSuchMethodErrorafter the broker is upgraded to a version containing #26030.Why
NoSuchMethodErroroccursBrokerInterceptorcallbacks such asmessageDispatchedreceive a brokerConsumerinstance. An existing extension can use the following API path:When this extension is compiled against an earlier Pulsar release, the Java compiler records the following symbolic method reference in the extension bytecode:
The relevant bytecode is equivalent to:
The extension does not get recompiled when the broker is upgraded. When the interceptor callback is executed, the JVM resolves the existing
invokevirtualreference against thePendingAcksMaploaded from the upgraded broker.After #26030, that exact method name and descriptor no longer exist. The newly added primitive accessor has a different name and return type:
The JVM cannot substitute one method for the other. Method resolution therefore fails with a linkage error similar to:
The interceptor can load successfully and only fail when the affected callback and call site are first executed, making the problem dependent on extension behavior and broker traffic.
Modifications
PendingAcksMap#get(long, long)JVM method signature available in previous releases.IntIntPairfrom the packed primitive value while holding the existing read lock.nullfor missing ledger and entry mappings, preserving the previous behavior.BrokerInterceptorextension fixture that accesses the method throughConsumer#getPendingAcks(), reproducing the extension API call path.Performance impact
The broker production paths changed by #26030 continue to use
getRemainingUnackedandremoveAndGetRemainingUnacked. They do not call the compatibility method and therefore do not recreateIntIntPairobjects on the pending-ack hot paths.An
IntIntPairis allocated only when an existing extension explicitly invokes the deprecated compatibility method.Verifying this change
The following targeted test and style checks pass:
Does this pull request potentially affect one of the following parts:
If the box was checked, please highlight the changes