-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Describe the bug
We encountered a MessageDeliveryException
during application shutdown.
The stack trace suggests that PostgresSubscribableChannel
was still processing messages in its pollAndDispatchMessage
loop while Spring had already unregistered the corresponding message handlers. This led to a org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
error.
From what I can tell, Spring shuts components down in the expected order, but any in-flight messages may no longer be dispatchable at that point.
Would it make sense for PostgresSubscribableChannel
to block on unsubscribe
calls while a message is being dispatched, and then exit the polling loop once the message handling has completed? Since this situation likely only occurs asynchronously during shutdown, relying on error handling seems fragile, as at that point Spring may have already stopped other required beans.
A test reproducing the situation can be found at https://github.com/bertschneider/spring-integration-notifyUpdate/blob/main/src/test/java/com/example/springintegration/SpringIntegrationITest.java
Stack trace:
org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:154) ~[spring-integration-core-6.5.1.jar:6.5.1]
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:121) ~[spring-integration-core-6.5.1.jar:6.5.1]
at org.springframework.integration.jdbc.channel.PostgresSubscribableChannel.dispatch(PostgresSubscribableChannel.java:231) ~[spring-integration-jdbc-6.5.1.jar:6.5.1]
at org.springframework.integration.jdbc.channel.PostgresSubscribableChannel.lambda$doPollAndDispatchMessage$4(PostgresSubscribableChannel.java:220) ~[spring-integration-jdbc-6.5.1.jar:6.5.1]
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:357) ~[spring-retry-2.0.12.jar:na]
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:230) ~[spring-retry-2.0.12.jar:na]
at org.springframework.integration.jdbc.channel.PostgresSubscribableChannel.lambda$doPollAndDispatchMessage$5(PostgresSubscribableChannel.java:220) ~[spring-integration-jdbc-6.5.1.jar:6.5.1]
at java.base/java.util.Optional.map(Optional.java:260) ~[na:na]
at org.springframework.integration.jdbc.channel.PostgresSubscribableChannel.doPollAndDispatchMessage(PostgresSubscribableChannel.java:220) ~[spring-integration-jdbc-6.5.1.jar:6.5.1]
at org.springframework.integration.jdbc.channel.PostgresSubscribableChannel.pollAndDispatchMessage(PostgresSubscribableChannel.java:190) ~[spring-integration-jdbc-6.5.1.jar:6.5.1]
at org.springframework.integration.jdbc.channel.PostgresSubscribableChannel.lambda$notifyUpdate$0(PostgresSubscribableChannel.java:183) ~[spring-integration-jdbc-6.5.1.jar:6.5.1]
at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]
Expected behavior
Processing of in-flight messages is finished.
In what version(s) of Spring Integration are you seeing this issue?
6.5.1