Skip to content

fix: prevent idle-close from shutting down in-use consumer, and avoid NPE in per-user pool aspect - #708

Open
yyqdbngt wants to merge 1 commit into
apache:masterfrom
yyqdbngt:fix/consumer-race-and-aspect-npe
Open

fix: prevent idle-close from shutting down in-use consumer, and avoid NPE in per-user pool aspect#708
yyqdbngt wants to merge 1 commit into
apache:masterfrom
yyqdbngt:fix/consumer-race-and-aspect-npe

Conversation

@yyqdbngt

Copy link
Copy Markdown

Motivation

Two concurrency / robustness bugs found while reviewing the message-query and admin-pool code:

  1. Idle-close task could shut down a consumer while it is still in use
    AutoCloseConsumerWrapper returns the shared DefaultMQPullConsumer and a background task closes it after 60s of idleness. The check-and-close runs on a separate scheduler thread with no knowledge of threads currently using the consumer, so a long-running query (e.g. scanning many queues in queryMessageByTopic) could have the consumer shut down mid-use, making the pull fail with an exception. Also, getConsumer handed out the consumer after releasing the lock, so the close could slip in between the null-check and the return.

    Fix: track an in-use counter. getConsumer now acquires the consumer and increments the counter under the same lock used by close(), and adds releaseConsumer() which the callers invoke in finally blocks. The idle-close task only proceeds when the counter is zero.

  2. MQAdminAspect could NPE when per-user isolation is enabled but no user is in context
    When loginRequired is on and the auth mode is not file, every non-whitelisted MQAdminExt method tries to borrow a per-user MQAdminExt using currentUserInfo.getUsername(). On background/scheduled threads there is no user in UserInfoContext, so this throws a NullPointerException. The aspect now falls back to the default pool when no user info is present.

Verification

mvn compiler:compile passes (BUILD SUCCESS).

Diff

3 files changed, +50 / -20.

… NPE in per-user pool aspect

- AutoCloseConsumerWrapper: acquire the consumer and increment an in-use
  counter under the same lock, so the idle-close task can never shut down
  a consumer that a thread is about to use or is already using
- MessageServiceImpl: release the consumer in finally blocks after use so
  the in-use counter returns to zero and idle close keeps working
- MQAdminAspect: fall back to the default MQAdminExt pool when a method
  requires per-user isolation but no user info is present in the thread
  context (e.g. background/scheduled tasks), instead of throwing NPE
@yyqdbngt
yyqdbngt force-pushed the fix/consumer-race-and-aspect-npe branch from ff16da4 to d73fec3 Compare July 31, 2026 15:33
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.

1 participant