从控制器中启动Kotlin的任务的范围是什么?

发布于 2025-02-12 19:04:50 字数 518 浏览 0 评论 0原文

我的Kotlin应用程序正在使用Spring揭示应该在后台执行长任务的API。我们需要返回

@PutMapping("/refresh")
fun refresh() = {
    GlobalScope.launch(IO) { refreshDataFromCache() }
    return ResponseEntity.accepted().body("""{"result": "accepted"}""")
}

Intellij抱怨说,使用GlobalsCope是一个反模式。但是,我不能仅将暂停添加到控制器函数,也不能正常工作。我都不能使用 runblocking ,或者该方法需要等到完成静止超时直到

我应该添加该功能的范围来使用结构的并发

My Kotlin App is using Spring to expose an API that should execute a long task in the background. We need to return

@PutMapping("/refresh")
fun refresh() = {
    GlobalScope.launch(IO) { refreshDataFromCache() }
    return ResponseEntity.accepted().body("""{"result": "accepted"}""")
}

IntelliJ complains that using the GlobalScope is an anti-pattern. However, I cannot just add suspend to the controller function or it won't work. Neither I can use runBlocking or the method will need to wait until finishing producing a REST timeout

What should I add as the scope of this function to use structured concurrency?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

合约呢 2025-02-19 19:04:50

您可能希望将除GlobalsCope以外的其他范围注入资源。如果您的框架已经提供了某种“应用程序范围”,这些范围将在您的应用程序关闭时被取消,那似乎是合适的。

失败 - Coroutine范围只是围绕工作的包装器(嗯,还有其他Coroutine上下文项目)。因此,您可以在应用程序启动期间创建一个新作业,而只需coroutinescope(job)即可使您的应用程序coroutine范围。然后,只需在应用程序关闭过程中执行job.cancel(),这将确保该范围中启动的任何coroutines都将被取消。

编辑以添加我的解决方案:

private val jobScope = CoroutineScope(IO)

@PutMapping("/refresh")
fun refresh() = {
    jobScope.launch(IO) { refreshDataFromCache() }
    return ResponseEntity.accepted().body("""{"result": "accepted"}""")
}

@PreDestroy
fun stopTasks() {
    jobScope.cancel("Closing app")
}

You probably want to inject some scope other than GlobalScope into your resource. If your framework already provides some sort of "application scope" that will be cancelled when your application shuts down, that seems appropriate.

Failing that -- a coroutine scope is just a wrapper around a Job (well, and other coroutine context items). So you can create a new Job during app startup, and simply CoroutineScope(job) to make your application coroutine scope. Then just do job.cancel() during app shutdown and that will ensure any coroutines launched in that scope will be cancelled.

Edited to add my solution:

private val jobScope = CoroutineScope(IO)

@PutMapping("/refresh")
fun refresh() = {
    jobScope.launch(IO) { refreshDataFromCache() }
    return ResponseEntity.accepted().body("""{"result": "accepted"}""")
}

@PreDestroy
fun stopTasks() {
    jobScope.cancel("Closing app")
}
坦然微笑 2025-02-19 19:04:50

为了利用结构化的并发性,如所述并行分解节中,您可以使用coroutinescope函数:

@PutMapping("/refresh")
suspend fun refresh() = coroutineScope {
    async { refreshDataFromCache() } // this will run in parallel
    ResponseEntity.accepted().body("""{"result": "accepted"}""")
}

refresh()应标记为暂停以使用coroutinescope

To leverage structured concurrency, as described here in the Parallel decomposition section, you can use coroutineScope function:

@PutMapping("/refresh")
suspend fun refresh() = coroutineScope {
    async { refreshDataFromCache() } // this will run in parallel
    ResponseEntity.accepted().body("""{"result": "accepted"}""")
}

refresh() should be marked as suspend to use coroutineScope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文