[ISSUE #11039] Track consumer group channel attribute for heartbeat-v2 withoutSub registration - #11040
Conversation
…beat-v2 withoutSub registration registerConsumerWithoutSub registers the channel in consumerTable but never calls ClientChannelAttributeHelper.addConsumerGroup, so with enableFastChannelEventProcess=true the fast channel-close path finds no group for the channel and leaves the dead consumer registered for up to channelExpiredTimeout (120s). A later full heartbeat cannot repair it because updateChannel returns false for an existing channel. Mirror the registerConsumer attribute bookkeeping.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #11040 +/- ##
=============================================
- Coverage 48.86% 48.78% -0.09%
+ Complexity 13796 13769 -27
=============================================
Files 1381 1381
Lines 101574 101576 +2
Branches 13213 13214 +1
=============================================
- Hits 49636 49549 -87
- Misses 45925 45981 +56
- Partials 6013 6046 +33 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Evidence chain (audit 2026-09-05): Before the fix — ff8f6f7 + regression test only (production change stashed): The test uses a real After the fix — branch tip 755debe, re-measured 2026-09-05: Claim verification for "a later full heartbeat on the same channel cannot repair it": |
RockteMQ-AI
left a comment
There was a problem hiding this comment.
Summary
Tracks the consumer group channel attribute during heartbeat-v2 withoutSub registration, ensuring the channel is correctly associated even when no subscription update is needed. Small, focused fix with appropriate test.
LGTM.
Automated review by github-manager-bot
Problem / Evidence
With
enableFastChannelEventProcess=true, the fast channel-close path inConsumerManager#doChannelCloseEventcleans up a consumer channel by iteratingClientChannelAttributeHelper.getConsumerGroups(channel). That attribute is only written in the fullregisterConsumer(r1branch).registerConsumerWithoutSub— the path taken by heartbeat-v2 whenever the client's subscription fingerprint is unchanged (withoutSub=true, the normal reconnect case after broker restart / idle connection drop) — registers the channel inconsumerTablebut never writes the attribute.Consequences (verified in code):
getConsumerGroupsreturns empty, the cleanup loop is skipped,doChannelCloseEventreturns false.updateChannelreturns false for an already-registered channel, soregisterConsumer'sr1-guardedaddConsumerGroupis not reached.The dead entry lingers in
consumerTableuntilscanNotActiveChannelexpires it (channelExpiredTimeout, default 120s), delayingUNREGISTER(ConsumerFilterManager cleanup) and leaving stale entries in consumer connection queries.Regression test
ConsumerManagerTest#testWithoutSubRegistrationRemovedOnFastChannelClosefails before the fix (removed == false, group still inconsumerTable) and passes after.Root cause / Fix
Mirror the
registerConsumerattribute bookkeeping inregisterConsumerWithoutSub: callClientChannelAttributeHelper.addConsumerGroup(channel, group)when the channel was added/updated and fast channel event processing is enabled.Priority
PRIORITY = 72:影响 26(broker 重启/连接重建场景下失效消费者在 consumerTable 残留至 120s,延迟 UNREGISTER 通知与过滤器清理,污染连接列表——心跳 v2 常规路径)+ 波及范围 12(ConsumerManager fast 路径,单方法)+ 可复现性 20(确定性单元测试,EmbeddedChannel)+ 维护价值 14(与 registerConsumer 既有模式对齐,修复极小)。FIX_CONFIDENCE = 85。
Tests
mvn -pl broker test -Dtest=ConsumerManagerTest#testWithoutSubRegistrationRemovedOnFastChannelCloseTests run: 1, Failures: 1Tests run: 1, Failures: 0mvn -pl broker test -Dtest=ConsumerManagerTest: 14/14mvn -pl broker test -Dtest=ConsumerManagerScannerTest,ClientManageProcessorTest: 9/9Risk
Low. The added attribute write only occurs on the
updateChannel == truebranch (new channel), same condition as the existingregisterConsumerbookkeeping;ClientChannelAttributeHelper.addConsumerGroupis a no-op for inactive channels. The attribute is consumed only by the fast close path, so behavior withoutenableFastChannelEventProcessis unchanged.Closes #11039