Какой CoroutineScope использовать для конечной точки Spring Boot WebFlux

В приложении Spring Boot WebFlux у нас есть несколько конечных точек (REST и GraphQL), которые возвращают Mono или Flux чего-либо. Код, который вызывают эти конечные точки, является неблокирующим, но вместо использования реактора мы хотели бы написать весь этот неблокирующий код с использованием сопрограмм Kotlin. Мы можем использовать такой метод, как kotlinx.coroutines.reactor.mono(), чтобы обернуть наши сопрограммы в Mono (и соответствующий метод flux() для результатов Flux).

Однако для вызова этих методов нам сначала понадобится CoroutineScope для обертывания всего запроса (и для обработки таких вещей, как отмена любых дочерних сопрограмм, которые запускает наша основная сопрограмма «точки входа»). Кажется, здесь есть несколько вариантов. Например, мы могли бы построить новый CoroutineScope и выбрать диспетчера, например CoroutineScope(Dispatchers.Default).mono {.... Или мы могли бы создать наш собственный класс, который представляет весь HTTP-запрос, и реализовать его CoroutineScope, как показано здесь для Android Activity.

В этом вопросе неявно подразумевается выбор потока (или пула потоков), над которым должна выполняться работа. Мы могли бы создать пул потоков сами, но Spring Boot WebFlux уже создал свой собственный пул потоков для обработки HTTP-запросов в неблокирующей среде, поэтому, может быть, лучше попытаться остаться в текущем потоке (или в этом пуле потоков)? Если это лучший способ, есть ли способ добраться до этого пула потоков и заставить сопрограмму работать на нем?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
3
0
1 776
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку в Spring WebFlux обмены HTTP не привязаны к конкретному потоку, GlobalScope.mono(Dispatchers.Unconfined), вероятно, является лучшим вариантом.

Обратите внимание, что Dispatchers.Unconfined - это экспериментальный API, а также API канала Coroutines, на который сильно повлияет ленивые итерируемые потоки. Поэтому я бы посоветовал вам подождать Официальная поддержка Spring для Coroutines для любого производственного кода.

Спасибо за ответ. В нем говорится, что здесь: «Код приложения обычно должен использовать определяемую приложением CoroutineScope, использование async или запуск на экземпляре GlobalScope крайне не рекомендуется». Есть ли объяснение, почему в этом случае можно использовать GlobalScope? (Я знаю, что мы не используем async или launch, но я думал, что предупреждение о GlobalScope применимо в целом.)

Yoni Gibbs 23.11.2018 19:53

Действительно, поскольку GlobalScope следует использовать очень осторожно на уровне фреймворка, поэтому я настоятельно рекомендую дождаться официальной поддержки, над которой мы работаем. Я думаю, мы получим CoroutineScope, который будет использоваться на уровне обмена HTTP, со всеми ошибками и правильно подключенными слушателями жизненного цикла.

Sébastien Deleuze 04.12.2018 10:48

Похоже, теперь это будет доступно в Spring Framework 5.2. См. здесь для отличного объяснения от @sdeleuze.

Yoni Gibbs 16.04.2019 17:04

Другие вопросы по теме