有没有办法在测试之间停止 micronaut 计划的工作?
Is there a way to stop a micronaut scheduled job between tests?
我有一个应用程序可以根据属性动态安排作业。它侦听 ServiceReadyEvent,然后安排作业。下面是一个可以通过工厂添加到上下文中的小示例。
class JobsLoader(
@param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler,
val myJobName: String
) : ApplicationEventListener<ServiceReadyEvent> {
override fun onApplicationEvent(event: ServiceReadyEvent?) {
taskScheduler.schedule("* * * * *", () -> println("running job $jobName"))
}
}
为了测试这段代码,我使用 kotest 进行了 Micronaut 测试。
@MicronautTest
class Job1Spec(
@param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler
) {
init {
"start job loader" {
val jobsLoader = JobsLoader("job1", taskScheduler)
jobsLoader.onApplicationEvent(ServiceReadyEvent(ServiceInstance.of("test", URL("http://localhost:8080"))))
}
"verify the job runs" {
//code here to verify the job ran and performed the correct calls
}
}
}
我也有另一个工作的第二次测试
@MicronautTest
class Job2Spec(
@param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler
) {
init {
"start job loader" {
val jobsLoader = JobsLoader("job2", taskScheduler)
jobsLoader.onApplicationEvent(ServiceReadyEvent(ServiceInstance.of("test", URL("http://localhost:8080"))))
}
"verify the job runs" {
//code here to verify the job ran and performed the correct calls
}
}
}
我的问题在于,在第二次测试期间,我看到第一份工作 still 在第二次测试期间 运行:
[INFO] 2020-09-10 12:57:00,005 pool-2-thread-1 running job job1
[INFO] 2020-09-10 12:57:00,009 pool-4-thread-1 running job job2
关于第一个 运行 测试的所有其他内容都已停止,除了作业的 运行ning。我发现它仍然是 运行ning,因为它在作业 运行.
期间由于 HttpClient 被关闭而抛出异常
我试过了
- 使用
rebuildContext = true
在测试之间重建测试上下文
- 在我的
JobsLoader
class 中跟踪预定的期货,然后在 afterSpec
函数中取消它们。当我去取消它们时,期货列表总是空的。
- 手动刷新 TaskScheduler 和 ExecutorService bean
测试都顺利通过,但它们充满了异常 - 特别是当我开始测试越来越多的工作时,除了我正在测试的工作之外,其他所有工作都不断失败。我不确定这是否是 kotest、micronaut 测试、调度程序、某些组合或其他完全不同的问题(我也看到了 vertx 日志,但我认为这不是问题所在)。我真的只需要想办法在下一次测试 运行 之前杀死这些 jobs/threads。
任何帮助或想法将不胜感激!
因此,在输入所有这些内容后,我几乎立即弄清楚了我的问题所在。我在我的测试中手动创建了一个作业,它不是 micronaut 上下文的一部分,所以这就是为什么当我去尝试取消作业时我的未来列表总是空的。
我更改了测试以加载作业并将其添加到上下文中:
var jobsLoader: JobsLoader? = null
override fun beforeSpec(spec: Spec) {
jobsLoader = JobsLoader(taskScheduler, getJobsConfiguration(), jobResolver, eventPublisher)
jobsLoader?.onApplicationEvent(ServiceReadyEvent(ServiceInstance.of("test", URL("http://localhost:8080"))))
super.beforeSpec(spec)
}
override fun afterSpec(spec: Spec) {
jobsLoader?.stopJobs()
super.afterSpec(spec)
}
然后在我的作业加载器中提供了一个函数来取消任何作业。
class JobsLoader(
@param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler,
val myJobName: String
) : ApplicationEventListener<ServiceReadyEvent> {
private val scheduledJobs = mutableListOf<ScheduledFuture<*>>()
override fun onApplicationEvent(event: ServiceReadyEvent?) {
val scheduledFuture = taskScheduler.schedule("* * * * *", () -> println("running job $jobName"))
scheduledJobs.add(scheduledFuture)
}
fun stopJobs() {
scheduledJobs.forEach { it.cancel(false) }
}
}
我有一个应用程序可以根据属性动态安排作业。它侦听 ServiceReadyEvent,然后安排作业。下面是一个可以通过工厂添加到上下文中的小示例。
class JobsLoader(
@param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler,
val myJobName: String
) : ApplicationEventListener<ServiceReadyEvent> {
override fun onApplicationEvent(event: ServiceReadyEvent?) {
taskScheduler.schedule("* * * * *", () -> println("running job $jobName"))
}
}
为了测试这段代码,我使用 kotest 进行了 Micronaut 测试。
@MicronautTest
class Job1Spec(
@param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler
) {
init {
"start job loader" {
val jobsLoader = JobsLoader("job1", taskScheduler)
jobsLoader.onApplicationEvent(ServiceReadyEvent(ServiceInstance.of("test", URL("http://localhost:8080"))))
}
"verify the job runs" {
//code here to verify the job ran and performed the correct calls
}
}
}
我也有另一个工作的第二次测试
@MicronautTest
class Job2Spec(
@param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler
) {
init {
"start job loader" {
val jobsLoader = JobsLoader("job2", taskScheduler)
jobsLoader.onApplicationEvent(ServiceReadyEvent(ServiceInstance.of("test", URL("http://localhost:8080"))))
}
"verify the job runs" {
//code here to verify the job ran and performed the correct calls
}
}
}
我的问题在于,在第二次测试期间,我看到第一份工作 still 在第二次测试期间 运行:
[INFO] 2020-09-10 12:57:00,005 pool-2-thread-1 running job job1
[INFO] 2020-09-10 12:57:00,009 pool-4-thread-1 running job job2
关于第一个 运行 测试的所有其他内容都已停止,除了作业的 运行ning。我发现它仍然是 运行ning,因为它在作业 运行.
期间由于 HttpClient 被关闭而抛出异常我试过了
- 使用
rebuildContext = true
在测试之间重建测试上下文
- 在我的
JobsLoader
class 中跟踪预定的期货,然后在afterSpec
函数中取消它们。当我去取消它们时,期货列表总是空的。 - 手动刷新 TaskScheduler 和 ExecutorService bean
测试都顺利通过,但它们充满了异常 - 特别是当我开始测试越来越多的工作时,除了我正在测试的工作之外,其他所有工作都不断失败。我不确定这是否是 kotest、micronaut 测试、调度程序、某些组合或其他完全不同的问题(我也看到了 vertx 日志,但我认为这不是问题所在)。我真的只需要想办法在下一次测试 运行 之前杀死这些 jobs/threads。
任何帮助或想法将不胜感激!
因此,在输入所有这些内容后,我几乎立即弄清楚了我的问题所在。我在我的测试中手动创建了一个作业,它不是 micronaut 上下文的一部分,所以这就是为什么当我去尝试取消作业时我的未来列表总是空的。
我更改了测试以加载作业并将其添加到上下文中:
var jobsLoader: JobsLoader? = null
override fun beforeSpec(spec: Spec) {
jobsLoader = JobsLoader(taskScheduler, getJobsConfiguration(), jobResolver, eventPublisher)
jobsLoader?.onApplicationEvent(ServiceReadyEvent(ServiceInstance.of("test", URL("http://localhost:8080"))))
super.beforeSpec(spec)
}
override fun afterSpec(spec: Spec) {
jobsLoader?.stopJobs()
super.afterSpec(spec)
}
然后在我的作业加载器中提供了一个函数来取消任何作业。
class JobsLoader(
@param:Named(TaskExecutors.SCHEDULED) val taskScheduler: TaskScheduler,
val myJobName: String
) : ApplicationEventListener<ServiceReadyEvent> {
private val scheduledJobs = mutableListOf<ScheduledFuture<*>>()
override fun onApplicationEvent(event: ServiceReadyEvent?) {
val scheduledFuture = taskScheduler.schedule("* * * * *", () -> println("running job $jobName"))
scheduledJobs.add(scheduledFuture)
}
fun stopJobs() {
scheduledJobs.forEach { it.cancel(false) }
}
}