Skip to content

fix(consumer): guard against disconnect() re-arming the reconnect loop - #55

Open
arsalan507 wants to merge 1 commit into
bitrix24:mainfrom
arsalan507:fix/graceful-disconnect-no-reconnect
Open

fix(consumer): guard against disconnect() re-arming the reconnect loop#55
arsalan507 wants to merge 1 commit into
bitrix24:mainfrom
arsalan507:fix/graceful-disconnect-no-reconnect

Conversation

@arsalan507

Copy link
Copy Markdown

Summary

Fixes #27.

connection.close() — called by disconnect() via super.disconnect() — still emits 'close' on the connection object, the exact same event the reconnect listener registered in connect() is watching for:

this.connection.on('close', () => { void this.handleReconnect() })

So a worker calling consumer.disconnect() to shut down cleanly would have its own close trigger handleReconnect(), which reconnects and reasserts the topology — resurrecting a connection the caller deliberately tore down.

Fix

Added an intentionalDisconnect flag:

  • disconnect() sets it to true before calling super.disconnect() (which closes the channel/connection).
  • The 'close' listener checks the flag and no-ops instead of calling handleReconnect() when it's set.
  • A successful connect() resets the flag to false, so a later broker-initiated drop on the same lifecycle still reconnects normally.

Test plan

  • Added a regression test (tests/consumer.test.ts) that calls disconnect(), simulates the resulting 'close' event (the fake connection's close() doesn't auto-emit it, so the test emits it explicitly to mirror real amqplib behavior), and asserts no setTimeout (i.e. no reconnect attempt) is scheduled. Verified it fails against the pre-fix code (setTimeout called with the reconnect interval) and passes after the fix.
  • pnpm lint, pnpm typecheck, pnpm test (76 passing), pnpm build all green.

connection.close() (called from disconnect() via super.disconnect())
still emits 'close' on the connection object, the same event the
reconnect listener in connect() is watching for. Without a way to tell
a deliberate shutdown apart from a broker drop, disconnect() itself
triggered handleReconnect() and resurrected the connection a caller
had just intentionally closed.

Add an intentionalDisconnect flag: disconnect() sets it before closing,
the 'close' listener no-ops when it is set, and a fresh connect() clears
it so a later broker drop on the same lifecycle still reconnects.

Fixes bitrix24#27
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.

fix(consumer): graceful disconnect() arms the reconnect loop — a worker that shuts down cleanly resurrects its connection

1 participant