Skip to content

Commit ce268a7

Browse files
authored
GH-2627: Deadlock on lifecycleMonitor Regression
Resolves #2627 Introduced by 73bee66 Remove the synchronization; it was added because an earlier implementation referenced `containers` which can only be used under the lock. When the implementation changed, I failed to remove the unnecessary sync. **cherry-pick to 2.9.x**
1 parent 802e47c commit ce268a7

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

spring-kafka/src/main/java/org/springframework/kafka/listener/ConcurrentMessageListenerContainer.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -350,18 +350,22 @@ protected void doStop(final Runnable callback, boolean normal) {
350350

351351
@Override
352352
public void childStopped(MessageListenerContainer child, Reason reason) {
353-
synchronized (this.lifecycleMonitor) {
354-
if (this.reason == null || reason.equals(Reason.AUTH)) {
355-
this.reason = reason;
356-
}
357-
if (Reason.AUTH.equals(this.reason)
358-
&& getContainerProperties().isRestartAfterAuthExceptions()
359-
&& this.concurrency == this.stoppedContainers.incrementAndGet()) {
353+
if (this.reason == null || reason.equals(Reason.AUTH)) {
354+
this.reason = reason;
355+
}
356+
if (Reason.AUTH.equals(this.reason)
357+
&& getContainerProperties().isRestartAfterAuthExceptions()
358+
&& this.concurrency == this.stoppedContainers.incrementAndGet()) {
359+
360+
this.reason = null;
361+
this.stoppedContainers.set(0);
360362

361-
this.reason = null;
362-
this.stoppedContainers.set(0);
363-
doStart();
363+
// This has to run on another thread to avoid a deadlock on lifecycleMonitor
364+
AsyncTaskExecutor exec = getContainerProperties().getListenerTaskExecutor();
365+
if (exec == null) {
366+
exec = new SimpleAsyncTaskExecutor(getListenerId() + ".authRestart");
364367
}
368+
exec.execute(() -> start());
365369
}
366370
}
367371

0 commit comments

Comments
 (0)