Skip to content

fix: close subscription consumers on GossClient.close() (leak from #33)#46

Merged
craigpnnl merged 1 commit into
developfrom
fix/gadp018-gossclient-consumer-leak
Jul 10, 2026
Merged

fix: close subscription consumers on GossClient.close() (leak from #33)#46
craigpnnl merged 1 commit into
developfrom
fix/gadp018-gossclient-consumer-leak

Conversation

@craigpnnl

Copy link
Copy Markdown
Contributor

Problem

GossClient.subscribe() created a DefaultClientConsumer but never stored it, so the JMS consumer and its listener thread were abandoned when the reference went out of scope, never deregistered from the broker. A long-running client that subscribes repeatedly leaks consumers.

Fix

  • Track subscription consumers and close each on GossClient.close() before the session closes.
  • Each close() is individually guarded so one throwing consumer cannot strand the remaining consumers or the session/connection teardown.
  • DefaultClientConsumer.close() guards a null messageConsumer (a partially-constructed consumer whose createConsumer() failed and was swallowed in the constructor), and logs a close failure at error instead of printing the stack trace.

Testing

GossClientConsumerLeakTest: subscribe tracks a consumer, close() closes and clears them, and a throwing consumer does not prevent the remaining teardown (the error-path regression guard). ./gradlew :pnnl.goss.core:build green.

Reviews

Reviewed for code quality, security (no half-open authenticated session, removes a resource-exhaustion vector), and failure handling (the guarded loop closes a leak-on-error path).

Related

Recovers the substantive fix from the stale, unmergeable PR #33 (closed), reworked fresh on current develop. Tracking #40.

…rce leak

subscribe() created a DefaultClientConsumer but never stored it, so the JMS
consumer and its listener thread were abandoned, never deregistered from the
broker. Track subscription consumers and close each on client close() before
the session closes. Each close() is individually guarded so one throwing
consumer cannot strand the remaining consumers or the session/connection
teardown. DefaultClientConsumer.close() guards a null messageConsumer (a
partially-constructed consumer) and logs a close failure at error instead of
printing the stack trace. Tests cover tracking, teardown, and the throwing
consumer error path.
@craigpnnl craigpnnl merged commit db1e3a1 into develop Jul 10, 2026
8 checks passed
@craigpnnl craigpnnl deleted the fix/gadp018-gossclient-consumer-leak branch July 10, 2026 19:24
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