Pull to refresh

Comments 26

Другими словами, язык Java недостаточно адаптирован к новым требованиям. В нем нет необходимых инструментов, делающих работу с асинхронным кодом более комфортным.

java.util.concurrent.CompletionStage (и RxJava как развитие)

Угу. CompletionStage это по сути Future в других языках. В Scala, например, Future'ы являются основной абстракцией для описания асинхронного кода, и на них определено множество комбинаторов для объединения и обработки асинхронных значений. Кроме того, с библиотеками типа scala-async код на Future'ах выглядит почти неотличимо от синхронного кода без них.


Кстати, в русскоязычной литературе continuation переводится как "продолжение".

Но, справедливости ради, scala-async и аналогичные механизмы в других языках в своей теоретической основе имеют как раз продолжения. Например, scala-async из async-блоков создаёт конечный автомат из продолжений, где код "после" вызовов await автоматически преобразуется в продолжение, которое будет вызвано после завершения асинхронного вызова.

UFO just landed and posted this here
Наверное, вы правы. С терминологией я явно перегнул палку… Жаргонизмы, используемые в разговоре с коллегами, не всегда подходит для публикаций. Вероятно, проработав с Java слишком долго я перестал их замечать.
UFO just landed and posted this here
Fiber — это не нить, а волокно. И в этом контексте особенно, ведь такое название пошло именно от аналогии с тем, что нить состоит из волокон, точно так же как fiber не является полноценным thread`ом, а несколько fiber`ов вливаются и составляют один полноценный thread (передавая управление друг другу внутри него через suspendable points). Так что в русском 3 слова, точно так же, как и в английском.
UFO just landed and posted this here

что делать, если клиент "завис" после получения СМС и не продолжает континуацию/фибру/корутину?
если таких клиентов накапливается тысячи, их фибры жрут память/стек.
как впендюрить механизм убивания "нежити"?
как решение: должны поддерживаться таймаутные операции — не ответил за пару часов, фибра убивается.
плюс объекты для фибр должны поддерживать псеводасинхронность: при обращении к ним фибра переключается на другую, пока эта не сможет продолжаться после "подводной" асинхронной работы.
пока имеем: псеводасинхронные операции с таймаутом. дальше.
как работать с GUI из фибры? обычно последние однопоточные в своих loopах.
в общем, должен быть целый фреймворк для работы с фибрами — те же файлы, сети, бд и тд, но в альтернативной реализации

В свое время искал решение для написания логики бизнес процессов на Java, что есть по сути обычная StateMachine. Хотелось бы, чтобы flow был написан натуральными конструкциями, но при этом код был асинхронный. Необходимо было: а) корутины, б) сериализация состояния, в) возможность полного перехватывания после suspend. Ничего не нашел, что бы могло бы на 100% удовлетворить.

На мой взгляд основное неудобство Quasar в том, что выполнение файберов сильно завязано на FiberScheduler (которых фреймворк предоставляет два: FiberExecutorScheduler и FiberThreadPoolScheduler). Вся магия выполнения лежит в нем. Если я хочу кастомно выполнять файбер после прерывания Continuation.continueWith©, как это делается в javaflow, то придется писать свой Scheduler.

Другое основное неудобство всех корутинных библиотек на Java — жесткое трюкачество на уровне байткода: требуется настройка тулзов и добавление агентов в рантайм. Все это сильно усложняет архитектуру, дебагинг и тесты.

Так что лучше подождем, пока официально запилят корутины Kotlin-е.

P.S. Добавьте еще одну библиотеку, которая на самый момент наиболее продвинутая — https://github.com/offbynull/coroutines
Работает с Java8. Основной недостаток — приходится въявную таскать во все suspendable-методы объект Continuation.
При инициализации FiberExecutorScheduler можно указать свой executor. В простейшем случае это будет выглядеть так

FiberScheduler scheduler = new FiberExecutorScheduler("MyScheduler", Runnable::run)


В принципе, можно сделать синглтон. Излишеством, на мой взгляд, злесь является экземпляр FiberTimedScheduler, который создается в конструкторе FiberExecutorScheduler безусловно.
Файберы — это не совсем континуации, это suspendable threads. Для континуаций не нужны никакие экзекьюторы. Весь экзекьютор — это простой цикл:
Continuation d = Continuation.startWith(new MySuspendable());
while(d!=null) {
d = Continuation.continueWith(d);
}
т.е. фактически выполняются вручную, что дает полный контроль выполнения, и что как бы и требуется для задачи: при необходимости можно сериализовать и сохранить состояние в БД, при получении внешнего месседжа загрузить континуацию и продолжить.

А поскольку файберы подобно тредам должны выполняться автоматически, им нужен внешний шедулер, который будет контролировать их выполнение. И чтобы свести случай к предыдущему, нужно писать свой шедулер. А в API квазара это как бы не совсем предусмотрено.

Ха, только успел подумал что надо посоветовать переходить на котлин, как на тебе:


Так что лучше подождем, пока официально запилят корутины Kotlin-е.

Вроде уже более-менее стабильны они, хотя официального релиза не было. Но Котлином люди игрались задолго до того как вообще версия 1.0 вышла. Смело берите свежий EAP и пробуйте.

Там пока корутины не сериализуемы. Обещают подумать над темой в будущих релизах.
Более, чем можно себе представить.Если мы хотим при помощи корутин определять долгоиграющие StateMachine-ы, то состояние после suspend-а хотелось бы персистить, а перед resume-ом восстанавливать. Юзкейсов десятки, от всяких WebFlow, BPM до high availability.
var user = await registerUser(request);
user.confCode = await generateConfirmationCode();
Task.Run(()=>sendSms("Confirmation code " + user.confCode));
return Response.ok;


То чувство когда как шарпист слегка злопыхаешь над мучениями жавистов в случае асинхронного кода))
UFO just landed and posted this here
Имненно для борьбы с комплеском неполноценности, провоцируемым оператором await в C#, был создан Java проект coroutines, о котором я не упомянул в статье.

Вообще, надо сказать, C# в плане эволюции является полным антиподом Java: язык очень агрессивно модифицируется. Иногда кажется, что скоро не останется слов английского языка, которые бы не были ключевыми словами в C#. Java в этом плане крайене консервативна. И мне такой подход ближе. В индустрии слишком сильно влияние моды, и поспешная адаптация языка может вызвать проблемы в будущем.
Чем плох Future? Идея такая же — выполнить в другом потоке и подождать результат обратно в текущий.
Дело не в Future, дело в том, как выглядит код, который его использует. Часто серверный код, выполненный в классическом стиле, выглядит дольно сложным. Но когда ты начинаешь писать асинхронный код, то понимаешь, насколько более сложным и путанным он может стать.
UFO just landed and posted this here
Я посчитал, что здесь важнее понимать, зачем все это нужно. Сами решения второстепенны. На мой взгляд, довольно важному вопросу уделяется недостаточно внимания. Собственно поэтому я и начал с философии…
Смотрел как-то на Quasar и запомнились 2 вещи — javaagent и использование в тестах Nanocloud, который очень часто использовал на работе.
Sign up to leave a comment.

Articles