Skip to content

fix(proxy): unregister all publishing topics on gRPC producer termination - #10665

Closed
btlqql wants to merge 1 commit into
apache:developfrom
btlqql:fix/grpc-producer-termination-unregister-all-topics
Closed

fix(proxy): unregister all publishing topics on gRPC producer termination#10665
btlqql wants to merge 1 commit into
apache:developfrom
btlqql:fix/grpc-producer-termination-unregister-all-topics

Conversation

@btlqql

@btlqql btlqql commented Jul 27, 2026

Copy link
Copy Markdown

痛点

gRPC producer 终止时,notifyClientTermination 中 grpcChannelManager.removeChannel(clientId) 被放在 for 循环内部。removeChannel 第一次调用时移除并返回 channel,后续迭代返回 null,导致只有第一个 publishing topic 被注销,其余 topic 的 producer 注册信息残留在 broker 端。

Fixes #10661

已实现

  • 将 grpcChannelManager.removeChannel(clientId) 移到 for 循环之前
  • channel 只移除一次,所有 publishing topic 均正确调用 unRegisterProducer

验证

  • 改动仅调整控制流顺序,不改变单次注销的语义
  • 本地无 Java 编译环境,依赖 CI 验证编译和测试
  • 改动文件:ClientActivity.java(5 行增 5 行删)

Signed-off-by: btlqql 2977859784@qq.com

…tion

In notifyClientTermination, grpcChannelManager.removeChannel(clientId)
was called inside the for-each loop over publishing topics. Since
removeChannel removes and returns the channel on the first call,
subsequent iterations received null and skipped unregistration. Only
the first topic was ever unregistered.

Move removeChannel before the loop so the channel is removed once and
all publishing topics are properly unregistered.

Fixes apache#10661

Signed-off-by: btlqql <2977859784@qq.com>

@RockteMQ-AI RockteMQ-AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review by github-manager-bot

Summary

Fixes a bug where gRPC producer termination only unregisters the first publishing topic from the broker, leaving stale producer registrations for remaining topics.

Analysis

Root Cause: In the original code, grpcChannelManager.removeChannel(clientId) was called inside the for loop that iterates over publishing topics. Since removeChannel removes and returns the channel on the first call, subsequent iterations return null. This means:

  • 1st topic: channel removed, producer unregistered ✓
  • 2nd+ topics: channel is null, unRegisterProducer skipped ✗

Fix: Move removeChannel(clientId) before the loop, store the result in a local variable, and reuse it for all topic unregistrations. This is correct and minimal.

Observations

  1. Correctness ✅ — The fix properly ensures all publishing topics are unregistered. The channel is removed exactly once and reused for every unRegisterProducer call.

  2. Consistency ✅ — The new code structure matches the existing pattern used for consumer cases (PUSH_CONSUMER, SIMPLE_CONSUMER) in the same method, which also call removeChannel once before processing.

  3. Scope ✅ — Minimal change (5+/5-) in a single file. No behavioral change to individual unregister semantics, only fixes the control flow ordering.

  4. Edge case — If getPublishing().getTopicsList() is empty, the channel is still removed (correct cleanup behavior). If removeChannel returns null (channel already removed), no unregistration is attempted (safe).

Verdict

Approve. Clean, correct fix for a real resource leak issue. Well-scoped and consistent with existing code patterns.

@fuyou001

Copy link
Copy Markdown
Contributor

Thanks for the fix. This PR duplicates #10662, which has already been merged into develop and addresses the same issue.

The merged change also includes regression coverage for unregistering multiple publishing topics with the same ClientChannelInfo, so this PR is no longer needed. Closing as a duplicate of #10662.

@fuyou001 fuyou001 closed this Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement] gRPC producer termination only unregisters the first publishing topic

4 participants