[英]What scope to use for launching a task in Kotlin from a controller?
我的 Kotlin 應用程序正在使用 Spring 公開一個應該在后台執行長任務的 API。 我們需要返回
@PutMapping("/refresh")
fun refresh() = {
GlobalScope.launch(IO) { refreshDataFromCache() }
return ResponseEntity.accepted().body("""{"result": "accepted"}""")
}
IntelliJ 抱怨說使用 GlobalScope 是一種反模式。 但是,我不能只將掛起添加到控制器功能,否則它將不起作用。 我不能使用runBlocking或者該方法需要等到完成產生 REST 超時
我應該添加什么作為此函數的范圍以使用結構化並發?
您可能希望將 GlobalScope 以外的一些范圍注入到您的資源中。 如果您的框架已經提供了某種“應用程序范圍”,當您的應用程序關閉時將取消該“應用程序范圍”,那么這似乎是合適的。
做不到這一點 - 協程范圍只是 Job (以及其他協程上下文項)的包裝器。 所以你可以在app啟動的時候創建一個新的Job,簡單CoroutineScope(job)
就可以讓你的應用成為協程范圍。 然后只需在應用程序關閉期間執行job.cancel()
,這將確保在該范圍內啟動的任何協程都將被取消。
編輯添加我的解決方案:
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")
}
要利用結構化並發,如並行分解部分中所述,您可以使用coroutineScope
函數:
@PutMapping("/refresh")
suspend fun refresh() = coroutineScope {
async { refreshDataFromCache() } // this will run in parallel
ResponseEntity.accepted().body("""{"result": "accepted"}""")
}
refresh()
應標記為suspend
以使用coroutineScope
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.