Комментарии 26
Другими словами, язык Java недостаточно адаптирован к новым требованиям. В нем нет необходимых инструментов, делающих работу с асинхронным кодом более комфортным.
java.util.concurrent.CompletionStage (и RxJava как развитие)
Угу. CompletionStage это по сути Future в других языках. В Scala, например, Future'ы являются основной абстракцией для описания асинхронного кода, и на них определено множество комбинаторов для объединения и обработки асинхронных значений. Кроме того, с библиотеками типа scala-async код на Future'ах выглядит почти неотличимо от синхронного кода без них.
Кстати, в русскоязычной литературе continuation переводится как "продолжение".
Но, справедливости ради, scala-async и аналогичные механизмы в других языках в своей теоретической основе имеют как раз продолжения. Например, scala-async из async
-блоков создаёт конечный автомат из продолжений, где код "после" вызовов await
автоматически преобразуется в продолжение, которое будет вызвано после завершения асинхронного вызова.
что делать, если клиент "завис" после получения СМС и не продолжает континуацию/фибру/корутину?
если таких клиентов накапливается тысячи, их фибры жрут память/стек.
как впендюрить механизм убивания "нежити"?
как решение: должны поддерживаться таймаутные операции — не ответил за пару часов, фибра убивается.
плюс объекты для фибр должны поддерживать псеводасинхронность: при обращении к ним фибра переключается на другую, пока эта не сможет продолжаться после "подводной" асинхронной работы.
пока имеем: псеводасинхронные операции с таймаутом. дальше.
как работать с GUI из фибры? обычно последние однопоточные в своих loopах.
в общем, должен быть целый фреймворк для работы с фибрами — те же файлы, сети, бд и тд, но в альтернативной реализации
На мой взгляд основное неудобство Quasar в том, что выполнение файберов сильно завязано на FiberScheduler (которых фреймворк предоставляет два: FiberExecutorScheduler и FiberThreadPoolScheduler). Вся магия выполнения лежит в нем. Если я хочу кастомно выполнять файбер после прерывания Continuation.continueWith©, как это делается в javaflow, то придется писать свой Scheduler.
Другое основное неудобство всех корутинных библиотек на Java — жесткое трюкачество на уровне байткода: требуется настройка тулзов и добавление агентов в рантайм. Все это сильно усложняет архитектуру, дебагинг и тесты.
Так что лучше подождем, пока официально запилят корутины Kotlin-е.
P.S. Добавьте еще одну библиотеку, которая на самый момент наиболее продвинутая — https://github.com/offbynull/coroutines
Работает с Java8. Основной недостаток — приходится въявную таскать во все suspendable-методы объект Continuation.
FiberScheduler scheduler = new FiberExecutorScheduler("MyScheduler", Runnable::run)
В принципе, можно сделать синглтон. Излишеством, на мой взгляд, злесь является экземпляр FiberTimedScheduler, который создается в конструкторе FiberExecutorScheduler безусловно.
Continuation d = Continuation.startWith(new MySuspendable());
while(d!=null) {
d = Continuation.continueWith(d);
}
т.е. фактически выполняются вручную, что дает полный контроль выполнения, и что как бы и требуется для задачи: при необходимости можно сериализовать и сохранить состояние в БД, при получении внешнего месседжа загрузить континуацию и продолжить.
А поскольку файберы подобно тредам должны выполняться автоматически, им нужен внешний шедулер, который будет контролировать их выполнение. И чтобы свести случай к предыдущему, нужно писать свой шедулер. А в API квазара это как бы не совсем предусмотрено.
Ха, только успел подумал что надо посоветовать переходить на котлин, как на тебе:
Так что лучше подождем, пока официально запилят корутины Kotlin-е.
Вроде уже более-менее стабильны они, хотя официального релиза не было. Но Котлином люди игрались задолго до того как вообще версия 1.0 вышла. Смело берите свежий EAP и пробуйте.
var user = await registerUser(request);
user.confCode = await generateConfirmationCode();
Task.Run(()=>sendSms("Confirmation code " + user.confCode));
return Response.ok;
То чувство когда как шарпист слегка злопыхаешь над мучениями жавистов в случае асинхронного кода))
Вообще, надо сказать, C# в плане эволюции является полным антиподом Java: язык очень агрессивно модифицируется. Иногда кажется, что скоро не останется слов английского языка, которые бы не были ключевыми словами в C#. Java в этом плане крайене консервативна. И мне такой подход ближе. В индустрии слишком сильно влияние моды, и поспешная адаптация языка может вызвать проблемы в будущем.
(на правах рекламы)
Континуации в Java