В приложении 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-запросов в неблокирующей среде, поэтому, может быть, лучше попытаться остаться в текущем потоке (или в этом пуле потоков)? Если это лучший способ, есть ли способ добраться до этого пула потоков и заставить сопрограмму работать на нем?




Поскольку в Spring WebFlux обмены HTTP не привязаны к конкретному потоку, GlobalScope.mono(Dispatchers.Unconfined), вероятно, является лучшим вариантом.
Обратите внимание, что Dispatchers.Unconfined - это экспериментальный API, а также API канала Coroutines, на который сильно повлияет ленивые итерируемые потоки. Поэтому я бы посоветовал вам подождать Официальная поддержка Spring для Coroutines для любого производственного кода.
Действительно, поскольку GlobalScope следует использовать очень осторожно на уровне фреймворка, поэтому я настоятельно рекомендую дождаться официальной поддержки, над которой мы работаем. Я думаю, мы получим CoroutineScope, который будет использоваться на уровне обмена HTTP, со всеми ошибками и правильно подключенными слушателями жизненного цикла.
Похоже, теперь это будет доступно в Spring Framework 5.2. См. здесь для отличного объяснения от @sdeleuze.
Спасибо за ответ. В нем говорится, что здесь: «Код приложения обычно должен использовать определяемую приложением CoroutineScope, использование async или запуск на экземпляре GlobalScope крайне не рекомендуется». Есть ли объяснение, почему в этом случае можно использовать
GlobalScope? (Я знаю, что мы не используемasyncилиlaunch, но я думал, что предупреждение оGlobalScopeприменимо в целом.)