gpt4 book ai didi

Launching coroutine in Ktor request handler(在KTOR请求处理程序中启动协程)

转载 作者:bug小助手 更新时间:2023-10-24 20:10:57 30 4
gpt4 key购买 nike



I want to instantly respond to the client and handle the request in the background by launching a coroutine. First i tried the following solution:

我希望立即响应客户端,并通过启动协程在后台处理请求。首先,我尝试了以下解决方案:


suspend fun PipelineContext<Unit, ApplicationCall>.handleTest(value: Unit) {
// insert calls to suspending functions here

launch {
repeat(10000) {
println("Executing background task $it.")
delay(1000)
}
}

call.respond("Executing the task in background")
}

routing {
get("/test", PipelineContext<Unit, ApplicationCall>::handleTest)
}

This works as expected. It returns instantly and executes the background task.
Though, IntelliJ IDE gives me the following warning:

这与预期的一样有效。它立即返回并执行后台任务。不过,IntelliJ IDE给了我以下警告:


Ambiguous coroutineContext due to CoroutineScope receiver of suspend function 

I know what this warning means and why it occurs, so I tried to find a way around this:

我知道这个警告的含义和发生的原因,所以我试图找到一种方法来解决这个问题:


suspend fun handleTest(context: PipelineContext<Unit, ApplicationCall>) {
// insert calls to suspending functions here

context.launch {
repeat(10000) {
println("Executing background task $it.")
delay(1000)
}
}

context.call.respond("Executing the task in background")
}

routing {
get("/test") {
handleTest(this)
}
}

This piece of code also works as expected, however it looks wrong to me when reading this article, https://elizarov.medium.com/explicit-concurrency-67a8e8fd9b25. The author explains that you should not launch coroutines inside a suspending function unless wrapping it in a new coroutineScope {}.

这段代码也能像预期的那样工作,但在我阅读本文https://elizarov.medium.com/explicit-concurrency-67a8e8fd9b25.时,它看起来是错误的作者解释说,除非将挂起函数包装在新的coroutineScope{}中,否则不应该在挂起函数中启动协程。


I was curious and tried out to inline handleTest:

我很好奇,试着内联HandleTest:


routing {
get("/test") {
// insert calls to suspending functions here

launch {
repeat(10000) {
println("Executing background task $it.")
delay(1000)
}
}

call.respond("Executing the task in background")
}
}

This also works as expected, and even the warning is gone. However, the construct is theoretically still the same as in the first solution.

这也像预期的那样起作用,甚至警告都消失了。然而,该构造在理论上仍然与第一个解决方案中的相同。


What is the correct solution to my problem?

我的问题的正确解决方案是什么?


更多回答
优秀答案推荐

You can use CoroutineScope:

您可以使用CoroutineScope:


routing {
get("/test") {
// insert calls to suspending functions here

CoroutineScope(Job()).launch {
repeat(10000) {
println("Executing background task $it.")
delay(1000)
}
}

call.respond("Executing the task in background")
}

It will create a new scope decouple the handler context.

它将创建一个新的作用域,分离处理程序上下文。



I suggest creating a new coroutine scope to make it clear from where the coroutineContext is taken because both CoroutineScope and suspend function have it.

我建议创建一个新的协程作用域,以明确从哪里获取coroutineContext,因为CoroutineScope和Suspend函数都有它。


suspend fun PipelineContext<Unit, ApplicationCall>.handleTest(value: Unit) = coroutineScope {
// insert calls to suspending functions here
launch {
repeat(10000) {
println("Executing background task $it.")
delay(1000)
}
}

call.respond("Executing the task in background")
}


You need to use withContext() with suspend functions, otherwise they would not suspend. Suspend is not same as blocking(where threads block). You need to use something similar to below:

您需要将with Context()与挂起函数一起使用,否则它们不会挂起。挂起不同于阻塞(线程阻塞)。您需要使用类似于以下内容的内容:


suspend fun handleTest(context: PipelineContext<Unit, ApplicationCall>) withContext(Dispatchers.Default) {
repeat(10000) {
println("Executing background task $it.")
delay(1000)
}
context.call.respond("Executing the task in background")

}

}


Blocking and Suspend for more details on blocking vs suspend

BLOCKING和SUSPEND,了解有关BLOCKING和SUSPEND的详细信息


更多回答

hey @NathanFallet it could lead to memory leaks if you don't handle properly your resources inside the bloc, maybe you're not closing some connections or you have some pointer to some structure that is not being cleaned. This code itself indeed is not generating a memory leak.

嘿@NathanFallet如果您没有正确处理块内的资源,可能会导致内存泄漏,可能是您没有关闭一些连接,或者您有一些指向某个结构的指针没有被清理。这段代码本身确实没有产生内存泄漏。

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com