I use AsyncConfigurer to implement asynchronous configuration
code show as below:
@Slf4j
@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {
@Bean
@Override
public Executor getAsyncExecutor() {
log.warn("-----------------start asyncServiceExecutor----------------");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(8);
executor.setMaxPoolSize(16);
executor.setQueueCapacity(64);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("SpringAsyncThread-");
executor.initialize();
// return executor;
return new HandlingExecutor(executor);
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SpringAsyncExceptionHandler();
}
class SpringAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
throwable.printStackTrace();
log.error("Exception occurs in async method", throwable.getMessage());
}
}
}
The configuration is successfully loaded, the console prints as follows when starting the project:
At this point I have an asynchronous method
schedulingService.acceptTask(task); This is a method whose return value is ListenableFuture
@PostMapping("processing")
public RestResult<Boolean> acceptTask(@RequestBody Task task) {
log.error(
"HPC服务接到任务处理-task的linkId:{},rootId{}",
task.getPipeLinkId().toHexString(),
task.getRootId().toHexString());
schedulingService.acceptTask(task);
return RestResult.success(true);
}
@PostMapping("wait/processing")
public RestResult<Boolean> acceptTaskWait(@RequestBody Task task) {
log.error(
"HPC服务接到任务处理-task的linkId:{},rootId{}",
task.getPipeLinkId().toHexString(),
task.getRootId().toHexString());
try {
return RestResult.success(schedulingService.acceptTask(task).get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return RestResult.success(true);
}
}
The schedulingService.acceptTask(task)
method execution error, it should throw an exception, but only I call
public RestResult<Boolean> acceptTaskWait(@RequestBody Task task)
will print out the exception information, but the problem is that I need to record the exception information of public RestResult<Boolean> acceptTask(@RequestBody Task task)
. I actually usepublic RestResult <Boolean> acceptTask(@RequestBody Task task)
method, but **AsyncUncaughtExceptionHandler**
does not play any role. When an exception occurs in my method, there is no information in the console.
I printed the log in the method as follows:
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
System.out.println("进入异常处理");
return new SpringAsyncExceptionHandler();
}
But it has not been implemented. I think this is a problem and it is very serious. If there is a good way, please tell me how to solve it and the reason for this problem. Thank you. The version of springboot I use is 2.2.7
Comment From: bclozel
I don't see anything specific to Spring Boot here, but rather an implementation/design issue about a particular use case.
I think you should create a new StackOverflow question and describe there what you're trying to achieve ans the problem you're facing. Also, it's not totally clear what RestResult
is and how it's being used.
Your controller completely ignores the resulting ListenableFuture
(again, we're missing code snippets here for schedulingService
) and doesn't store task status information anywhere, which is probably one of the cause of your problem here.
Thanks!