Kotlin ktor 库不等待所有协程在 websockets 处理程序中完成
Kotlin ktor library don't wait for all coroutines to finish in websockets handler
最近我试图用 Kotlin 和 ktor 库实现简单的网络套接字应用程序。我的服务器只有一个网络套接字处理程序,我按如下方式实现:
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
install(WebSockets)
routing {
webSocket("/handle") {
// ... more domain specific logic which uses coroutines ...
launch {
for (message in incoming) {
// process message
}
}
}
}
}
原始代码包含更多逻辑,其中包括启动一堆另一个协程 - 所以 launch
-ing incoming
在单独的协程中处理队列对我来说并不奇怪。
不幸的是,ktor
会在内部块功能完成后立即关闭底层网络套接字连接。这对我来说是意想不到的行为,因为我认为 webSocket
函数的行为类似于 coroutineScope
标准函数,它会等待所有附加的协程完成后再继续执行。
这个错误对我来说很难发现,所以我想更深入地了解 webSocket
功能的设计。所以,我有以下问题:
- 为什么
webSocket
函数不等待附加的协程?是bug还是有意为之?
- 关于处理
coroutineScope
-s 的函数的约定是什么?我是否应该始终使用已知的标准库函数(如 coroutineScope
)保护我的协程?或者库编写者是否应该遵循一些准则——例如,始终等待范围内所有附加的协程完成?
- 此行为很久以前就已实现,但 structured concurrency in mind. I'd say it's a problem that can be fixed on the Ktor side so I've created this issue 并未加以解决。修复将使编写 Websocket 处理程序变得更容易,并将提高可读性。
- 这取决于库维护者是否考虑在特定情况下支持结构化并发。
最近我试图用 Kotlin 和 ktor 库实现简单的网络套接字应用程序。我的服务器只有一个网络套接字处理程序,我按如下方式实现:
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
install(WebSockets)
routing {
webSocket("/handle") {
// ... more domain specific logic which uses coroutines ...
launch {
for (message in incoming) {
// process message
}
}
}
}
}
原始代码包含更多逻辑,其中包括启动一堆另一个协程 - 所以 launch
-ing incoming
在单独的协程中处理队列对我来说并不奇怪。
不幸的是,ktor
会在内部块功能完成后立即关闭底层网络套接字连接。这对我来说是意想不到的行为,因为我认为 webSocket
函数的行为类似于 coroutineScope
标准函数,它会等待所有附加的协程完成后再继续执行。
这个错误对我来说很难发现,所以我想更深入地了解 webSocket
功能的设计。所以,我有以下问题:
- 为什么
webSocket
函数不等待附加的协程?是bug还是有意为之? - 关于处理
coroutineScope
-s 的函数的约定是什么?我是否应该始终使用已知的标准库函数(如coroutineScope
)保护我的协程?或者库编写者是否应该遵循一些准则——例如,始终等待范围内所有附加的协程完成?
- 此行为很久以前就已实现,但 structured concurrency in mind. I'd say it's a problem that can be fixed on the Ktor side so I've created this issue 并未加以解决。修复将使编写 Websocket 处理程序变得更容易,并将提高可读性。
- 这取决于库维护者是否考虑在特定情况下支持结构化并发。