Warn when SimpleAsyncTaskExecutor is used
Issue: SPR-16203
This commit is contained in:
@@ -30,6 +30,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.core.task.SyncTaskExecutor;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
@@ -62,6 +63,9 @@ public final class WebAsyncManager {
|
||||
|
||||
private static final Object RESULT_NONE = new Object();
|
||||
|
||||
private static final AsyncTaskExecutor DEFAULT_TASK_EXECUTOR =
|
||||
new SimpleAsyncTaskExecutor(WebAsyncManager.class.getSimpleName());
|
||||
|
||||
private static final Log logger = LogFactory.getLog(WebAsyncManager.class);
|
||||
|
||||
private static final UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
@@ -72,10 +76,12 @@ public final class WebAsyncManager {
|
||||
private static final DeferredResultProcessingInterceptor timeoutDeferredResultInterceptor =
|
||||
new TimeoutDeferredResultProcessingInterceptor();
|
||||
|
||||
private static Boolean taskExecutorWarning = true;
|
||||
|
||||
|
||||
private AsyncWebRequest asyncWebRequest;
|
||||
|
||||
private AsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor(this.getClass().getSimpleName());
|
||||
private AsyncTaskExecutor taskExecutor = DEFAULT_TASK_EXECUTOR;
|
||||
|
||||
private volatile Object concurrentResult = RESULT_NONE;
|
||||
|
||||
@@ -280,6 +286,9 @@ public final class WebAsyncManager {
|
||||
if (executor != null) {
|
||||
this.taskExecutor = executor;
|
||||
}
|
||||
else {
|
||||
logExecutorWarning();
|
||||
}
|
||||
|
||||
List<CallableProcessingInterceptor> interceptors = new ArrayList<>();
|
||||
interceptors.add(webAsyncTask.getInterceptor());
|
||||
@@ -333,6 +342,33 @@ public final class WebAsyncManager {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
private void logExecutorWarning() {
|
||||
if (taskExecutorWarning && logger.isWarnEnabled()) {
|
||||
synchronized (DEFAULT_TASK_EXECUTOR) {
|
||||
AsyncTaskExecutor executor = this.taskExecutor;
|
||||
if (taskExecutorWarning &&
|
||||
(executor instanceof SimpleAsyncTaskExecutor || executor instanceof SyncTaskExecutor)) {
|
||||
String executorTypeName = executor.getClass().getSimpleName();
|
||||
logger.warn("\n!!!\n" +
|
||||
"An Executor is required to handle java.util.concurrent.Callable return values.\n" +
|
||||
"Please, configure a TaskExecutor in the MVC config under \"async support\".\n" +
|
||||
"The " + executorTypeName + " currently in use is not suitable under load.\n" +
|
||||
"-------------------------------\n" +
|
||||
"Request URI: '" + formatRequestUri() + "'\n" +
|
||||
"!!!");
|
||||
taskExecutorWarning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String formatRequestUri() {
|
||||
HttpServletRequest request = this.asyncWebRequest.getNativeRequest(HttpServletRequest.class);
|
||||
return request != null ? request.getRequestURI() : "servlet container";
|
||||
}
|
||||
|
||||
|
||||
private void setConcurrentResultAndDispatch(Object result) {
|
||||
synchronized (WebAsyncManager.this) {
|
||||
if (this.concurrentResult != RESULT_NONE) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -115,7 +115,7 @@ public class WebAsyncManagerTests {
|
||||
verifyDefaultAsyncScenario();
|
||||
verify(interceptor).beforeConcurrentHandling(this.asyncWebRequest, task);
|
||||
verify(interceptor).preProcess(this.asyncWebRequest, task);
|
||||
verify(interceptor).postProcess(this.asyncWebRequest, task, new Integer(concurrentResult));
|
||||
verify(interceptor).postProcess(this.asyncWebRequest, task, concurrentResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -161,9 +161,9 @@ public class WebAsyncManagerTests {
|
||||
|
||||
assertFalse(this.asyncManager.hasConcurrentResult());
|
||||
|
||||
verify(this.asyncWebRequest).addTimeoutHandler((Runnable) notNull());
|
||||
verify(this.asyncWebRequest).addErrorHandler((Consumer<Throwable>) notNull());
|
||||
verify(this.asyncWebRequest).addCompletionHandler((Runnable) notNull());
|
||||
verify(this.asyncWebRequest).addTimeoutHandler(notNull());
|
||||
verify(this.asyncWebRequest).addErrorHandler(notNull());
|
||||
verify(this.asyncWebRequest).addCompletionHandler(notNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -303,9 +303,9 @@ public class WebAsyncManagerTests {
|
||||
|
||||
assertFalse(this.asyncManager.hasConcurrentResult());
|
||||
|
||||
verify(this.asyncWebRequest).addTimeoutHandler((Runnable) notNull());
|
||||
verify(this.asyncWebRequest).addErrorHandler((Consumer<Throwable>) notNull());
|
||||
verify(this.asyncWebRequest).addCompletionHandler((Runnable) notNull());
|
||||
verify(this.asyncWebRequest).addTimeoutHandler(notNull());
|
||||
verify(this.asyncWebRequest).addErrorHandler(notNull());
|
||||
verify(this.asyncWebRequest).addCompletionHandler(notNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -353,7 +353,7 @@ public class WebAsyncManagerTests {
|
||||
@Test
|
||||
public void startDeferredResultProcessingNullInput() throws Exception {
|
||||
try {
|
||||
this.asyncManager.startDeferredResultProcessing((DeferredResult<?>) null);
|
||||
this.asyncManager.startDeferredResultProcessing(null);
|
||||
fail("Expected exception");
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
@@ -368,9 +368,9 @@ public class WebAsyncManagerTests {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void verifyDefaultAsyncScenario() {
|
||||
verify(this.asyncWebRequest).addTimeoutHandler((Runnable) notNull());
|
||||
verify(this.asyncWebRequest).addErrorHandler((Consumer<Throwable>) notNull());
|
||||
verify(this.asyncWebRequest).addCompletionHandler((Runnable) notNull());
|
||||
verify(this.asyncWebRequest).addTimeoutHandler(notNull());
|
||||
verify(this.asyncWebRequest).addErrorHandler(notNull());
|
||||
verify(this.asyncWebRequest).addCompletionHandler(notNull());
|
||||
verify(this.asyncWebRequest).startAsync();
|
||||
verify(this.asyncWebRequest).dispatch();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user