【问题标题】:Which CoroutineScope to use for Spring Boot WebFlux endpoint哪个 CoroutineScope 用于 Spring Boot WebFlux 端点
【发布时间】:2019-04-25 21:52:40
【问题描述】:

在 Spring Boot WebFlux 应用程序中,我们有许多端点(REST 和 GraphQL),它们返回 MonoFlux 的东西。这些端点调用的代码都是非阻塞的,但与其使用反应器,我们更愿意使用 Kotlin 协程来编写所有这些非阻塞代码。我们可以使用kotlinx.coroutines.reactor.mono() 之类的方法将我们的协程包装在Mono 中(以及对应的flux() 方法用于Flux 结果)。

但是,为了调用这些方法,我们首先需要一个 CoroutineScope 来包装整个请求(并处理诸如取消我们的主“入口点”协程启动的任何子协程之类的事情)。这里似乎有几个选择。例如,我们可以构造一个新的CoroutineScope 并选择一个调度程序,例如CoroutineScope(Dispatchers.Default).mono {...。或者,我们可以构建自己的类来表示整个 HTTP 请求,并实现 CoroutineScope,如 Android Activityhere 所示。

这个问题隐含的是选择应该在哪个线程(或线程池)上执行工作。我们可以自己创建一个线程池,但是 Spring Boot WebFlux 已经创建了自己的线程池,用于在非阻塞环境中处理 HTTP 请求,所以也许最好尝试留在当前线程(或那个线程池中)?如果这是最好的方法,有没有办法进入该线程池并让协程在其上运行?

【问题讨论】:

    标签: spring-boot kotlin spring-webflux project-reactor kotlinx.coroutines


    【解决方案1】:

    由于在 Spring WebFlux 中,HTTP 交换不是针对特定线程的潮流,GlobalScope.mono(Dispatchers.Unconfined) 可能是最好的选择。

    请注意,Dispatchers.Unconfined 是一个实验性 API,以及将受到 lazy iterable streams 深刻影响的协程通道 API。因此,我建议您等待 Spring official support for Coroutines 获取任何生产代码。

    【讨论】:

    • 感谢您的回复。它说here “应用程序代码通常应该使用应用程序定义的 CoroutineScope,强烈建议不要在 GlobalScope 的实例上使用异步或启动。”有没有解释为什么在这种情况下可以使用GlobalScope? (我知道我们没有使用asynclaunch,但我认为关于GlobalScope 的警告一般适用。)
    • 确实,因为GlobalScope 应该在框架级别非常谨慎地使用,这就是为什么我强烈建议等待我们正在努力的官方支持。我想我们最终会得到一个CoroutineScope,它将在 HTTP 交换级别使用,所有错误,生命周期侦听器都正确连接。
    • 看起来这将在 Spring Framework 5.2 中可用。请参阅 here 以获取来自 @sdeleuze 的出色解释。
    猜你喜欢
    • 2021-01-17
    • 2019-08-15
    • 2022-12-22
    • 2021-01-15
    • 2018-09-27
    • 2018-03-17
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    相关资源
    最近更新 更多