有没有一种方法可以在两次测试之间停止微导航计划的工作?

问题描述

我有一个可以根据属性动态调度作业的应用程序。它侦听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",URL("http://localhost:8080"))))
        }

        "verify the job runs" {
            //code here to verify the job ran and performed the correct calls
        }

    }   
}

我的问题在于,在第二次测试期间,我看到在第二次测试运行期间第一项任务仍是 计划>

[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 

关于第一次运行测试的所有其他操作都已停止,除了作业的运行。我发现它仍在运行,因为由于HttpClient在作业运行期间被关闭而引发了异常。

我尝试过

  • 使用rebuildContext = true在测试之间重建测试上下文
  • 在我的JobsLoader类中跟踪预定的期货,然后在afterSpec函数中将其取消。到我取消期货时,期货清单始终是空的。
  • 手动刷新TaskScheduler和ExecutorService Bean

所有测试都可以顺利通过,但是它们充满了异常-尤其是当我要测试越来越多的工作时,除了我正在测试的工作之外,其他所有工作都持续失败。我不确定这是否是kotest,micronaut测试,调度程序,某些组合或其他任何问题(我也看到了vertx日志,但我不认为这是问题)。我真的只需要在下一次测试运行之前找出一种杀死这些作业/线程的方法。

任何帮助或想法将不胜感激!

解决方法

因此,在输入所有内容后,我几乎立即发现了我的问题。我正在测试中手动创建作业,这不是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) }
    }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...