Run listener/send task locally as fallback on RejectedExecutionException

Closes gh-32171
This commit is contained in:
Juergen Hoeller 2024-02-01 11:07:02 +01:00
parent b61552b9df
commit 3d4d68c26f
2 changed files with 21 additions and 6 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.context.event;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -143,7 +144,13 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
Executor executor = getTaskExecutor();
for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
if (executor != null && listener.supportsAsyncExecution()) {
executor.execute(() -> invokeListener(listener, event));
try {
executor.execute(() -> invokeListener(listener, event));
}
catch (RejectedExecutionException ex) {
// Probably on shutdown -> invoke listener locally instead
invokeListener(listener, event);
}
}
else {
invokeListener(listener, event);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ package org.springframework.messaging.support;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
@ -96,11 +97,18 @@ public class ExecutorSubscribableChannel extends AbstractSubscribableChannel {
public boolean sendInternal(Message<?> message, long timeout) {
for (MessageHandler handler : getSubscribers()) {
SendTask sendTask = new SendTask(message, handler);
if (this.executor == null) {
sendTask.run();
if (this.executor != null) {
try {
this.executor.execute(sendTask);
}
catch (RejectedExecutionException ex) {
// Probably on shutdown -> run send task locally instead
sendTask.run();
}
}
else {
this.executor.execute(sendTask);
// No executor configured -> always run send tasks locally
sendTask.run();
}
}
return true;