Sophisticated lifecycle support for ThreadPoolTaskExecutor/Scheduler
Pause/resume capability through SmartLifecycle implementation. ContextClosedEvent triggers early executor/scheduler shutdown. Programmatic initiateShutdown() option for custom early shutdown. Closes gh-30831 Closes gh-27090 Closes gh-24497
This commit is contained in:
@@ -26,6 +26,7 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -96,9 +97,8 @@ public class EnableAsyncTests {
|
||||
public void properExceptionForExistingProxyDependencyMismatch() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AsyncConfig.class, AsyncBeanWithInterface.class, AsyncBeanUser.class);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
|
||||
ctx::refresh)
|
||||
.withCauseInstanceOf(BeanNotOfRequiredTypeException.class);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(ctx::refresh)
|
||||
.withCauseInstanceOf(BeanNotOfRequiredTypeException.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@@ -106,9 +106,8 @@ public class EnableAsyncTests {
|
||||
public void properExceptionForResolvedProxyDependencyMismatch() {
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AsyncConfig.class, AsyncBeanUser.class, AsyncBeanWithInterface.class);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(
|
||||
ctx::refresh)
|
||||
.withCauseInstanceOf(BeanNotOfRequiredTypeException.class);
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(ctx::refresh)
|
||||
.withCauseInstanceOf(BeanNotOfRequiredTypeException.class);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
@@ -142,13 +141,18 @@ public class EnableAsyncTests {
|
||||
context.getBean(AsyncBeanWithExecutorQualifiedByExpressionOrPlaceholder.class);
|
||||
|
||||
Future<Thread> workerThread1 = asyncBean.myWork1();
|
||||
assertThat(workerThread1.get().getName()).startsWith("myExecutor1-");
|
||||
assertThat(workerThread1.get(100, TimeUnit.MILLISECONDS).getName()).startsWith("myExecutor1-");
|
||||
|
||||
context.stop();
|
||||
Future<Thread> workerThread2 = asyncBean.myWork2();
|
||||
assertThat(workerThread2.get().getName()).startsWith("myExecutor2-");
|
||||
assertThatExceptionOfType(TimeoutException.class).isThrownBy(
|
||||
() -> workerThread2.get(100, TimeUnit.MILLISECONDS));
|
||||
|
||||
context.start();
|
||||
assertThat(workerThread2.get(100, TimeUnit.MILLISECONDS).getName()).startsWith("myExecutor2-");
|
||||
|
||||
Future<Thread> workerThread3 = asyncBean.fallBackToDefaultExecutor();
|
||||
assertThat(workerThread3.get().getName()).startsWith("SimpleAsyncTaskExecutor");
|
||||
assertThat(workerThread3.get(100, TimeUnit.MILLISECONDS).getName()).startsWith("SimpleAsyncTaskExecutor");
|
||||
}
|
||||
finally {
|
||||
System.clearProperty("myExecutor");
|
||||
@@ -208,8 +212,7 @@ public class EnableAsyncTests {
|
||||
@SuppressWarnings("resource")
|
||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(AspectJAsyncAnnotationConfig.class);
|
||||
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(
|
||||
ctx::refresh);
|
||||
assertThatExceptionOfType(BeanDefinitionStoreException.class).isThrownBy(ctx::refresh);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -521,6 +524,7 @@ public class EnableAsyncTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableAsync
|
||||
static class AsyncWithExecutorQualifiedByExpressionConfig {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
@@ -86,10 +86,20 @@ public class EnableSchedulingTests {
|
||||
assertThat(ctx.getBean(ScheduledTaskHolder.class).getScheduledTasks()).hasSize(1);
|
||||
|
||||
Thread.sleep(100);
|
||||
assertThat(ctx.getBean(AtomicInteger.class).get()).isGreaterThanOrEqualTo(10);
|
||||
ctx.stop();
|
||||
int count1 = ctx.getBean(AtomicInteger.class).get();
|
||||
assertThat(count1).isGreaterThanOrEqualTo(10);
|
||||
Thread.sleep(100);
|
||||
int count2 = ctx.getBean(AtomicInteger.class).get();
|
||||
assertThat(count2).isEqualTo(count1);
|
||||
ctx.start();
|
||||
Thread.sleep(100);
|
||||
int count3 = ctx.getBean(AtomicInteger.class).get();
|
||||
assertThat(count3).isGreaterThanOrEqualTo(20);
|
||||
|
||||
assertThat(ctx.getBean(ExplicitSchedulerConfig.class).threadName).startsWith("explicitScheduler-");
|
||||
assertThat(Arrays.asList(ctx.getDefaultListableBeanFactory().getDependentBeans("myTaskScheduler")).contains(
|
||||
TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)).isTrue();
|
||||
TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user