Event Bus Stops Receiving at the Shutdown Signal
Applies to 1.3.0.
Does this apply to you?
You need to check your code only if both are true:
- you pass an
eventBustocreateServer()(or start a bus yourself withstart({ signal })or thesignaloption); - something relies on a message that arrives after the shutdown began still being handled by that service instance.
A service whose handlers are idempotent and whose broker redelivers unacknowledged messages needs no changes.
What changed
server.stop() aborts the server's shutdown signal first and stops the bus by a shutdown hook later, up to shutdown.timeout after the abort. Until 1.3.0 the bus kept receiving in that interval: a message that arrived started a handler whose ctx.signal was already aborted. The retry middleware does not retry after a cancellation, so a transient failure went straight to the dead-letter queue when one was configured.
From 1.3.0 the bus stops receiving when the signal aborts:
- it ends its subscriptions;
- a delivery that is already on its way is returned to the broker with a requeue, so it is handled after the restart or by another consumer of the group;
- handlers that are running are not touched: they finish, can still publish through
ctx.publish, andstop()drains them and disconnects as before; - the subscriptions are ended once, whichever of the abort and
stop()comes first.
A bus you start yourself behaves the same way with its own signal: after the abort it handles no delivery, but publish() keeps working until stop() releases it. Starting a bus with a signal that is already aborted subscribes and ends the subscriptions at once.
Required changes
Usually none. Check these cases:
- You count on a last message being handled during shutdown. It is now handled by the next instance. Make sure the handler is idempotent, as at-least-once delivery already requires.
- You abort a signal that you gave to a bus and then keep using it for receiving. Do not abort it until you want reception to end; call
bus.stop()to release the bus. - You use your own signal for other purposes. The bus reacts to the signal you pass it, so pass a signal whose abort means "stop receiving".
Verify the upgrade
In a test with a real or in-memory broker, start the service, begin a slow handler, call server.stop() without awaiting it, publish a message and check that the slow handler finishes and the new message is not handled by this instance but is delivered to the next one.