Комментарии 15
Реактивный/асинхронный стиль программирования становится практически не нужным.
Если так, то как реализовать логику: после того как выполнилось это, выполни вот то в неблокирующем стиле?
это();
то();
Совершенно верно. Для виртуальных потоков нужно писать прямой последовательный код без всякой реактивщины. И этот факт вызывает у меня восхищение.
ну справедливости ради, реактивщина используется для экономии ресурсов, а под ресурсами может быть не только треды, но и что угодно - сетевые пулы, файловые пулы и т.д.
Реактивщина предназначена для максимальной утилизации CPU (а также может использоваться для удобного дизайна конвейера обработки с учётом back-pressure и удобного способа из коробки для балансировка различных подзадач).
Ни для какой экономии ресурсов она не ПРЕДНАЗНАЧЕНА (хотя конечно CPU экономиться будет).
Если вы всё ещё не верите, то постарайтесь ПОНЯТЬ как она работает, и у вас отпадут все вопросы.
PS: пришлось писать длинный ответ, так как не хватило кармы минусануть ))
вы вот так одним махом перечеркнули reactive-благодетели, такие как circuit breaking, throttling
понятно что reactive рожден для решения проблемы максимальной утилизации cpu для многопоточных приложений, но часть фишек reactive достаются бесплатно. и зачем от них отказываться.
вот есть у нас ограниченный по мощности сервис, он может принимать не более 5 одновременных запросов. если уже сидите на reactive фреймворке, то задача решается элементарно через созданием отдельного scheduler'а. и из коробки у вас есть и ограничение на одновременные запросы, и обработка ошибок при превышении лимитов, и удобный рычаг, который можно крутить в большую или меньшую сторону для управления нагрузкой.
как в случае:
это();
то();
управлять лимитами, мне не очевидно. но наверно тоже можно. мой комментарий был про эту неочевидность.
>> управлять лимитами... circuit breaking, throttling (с различными политиками), разные retries, и др вкусные фишки ))
Извините, но это вспомогательная элементы, которые вам предоставляет библиотека, так как это легко и гармонично вписывается в ее архитектуру.
Но это дополнительные инструменты.
Вы же чётко написали "реактивщина используется для экономии ресурсов". А это в целом совершенно неверно, так говорить нельзя ))
Реактивщина в целом используется именно для максимального/неэкономного использования ресурсов. Да, если какого-то вида ресурсов не хватает то мы можем использовать соответствующие rx-операторы в нужных узких местах.
Если же ресурсов в целом недостаточно, то зачем вообще писать сложный rx код (он сложный по определению, сложный в отладке, и тд)? Ограничить ресурс вы можете просто семафором, остальное фишки - сделать какими-то либами, но при этом будете иметь простой легко читаемый нереактивный код вашей бизнес-логики, который может поддерживаться программистом любой квалификации.
мне нравится ваша категоричность ;))
ок, чтобы знать на будущее, как называется ситуация, когда у нас есть ограниченный ресурс (отсутствует бюджет на расширение мощностей, либо это произойдет в будущем) и нам необходимо сегодня с этим ресурсом эффективно взаимодействовать. если это не экономия ресурсов, то что?
Мой последний комментарий!
Очень точная пословица о вашей логике: "В огороде бузина, а в Киеве - дядька" )))
Или по программистски:
Исходя и вашей логики, любой язык "используется" для экономии (поскольку он имеет какие-то способы оптимизации).
Даже multi-threading (как бы это дико не звучало) используется для экономии, т.к. там есть семафор!
вот есть у нас ограниченный по мощности сервис, он может принимать не более 5 одновременных запросов. если уже сидите на reactive фреймворке, то задача решается элементарно через созданием отдельного scheduler'а [...]
…который нихрена не помогает, потому что ограничивает степень параллелизма лишь при исполнении кода, но не при ожидании ответа от сервиса.
до чего техника дошла... (с)
По факту это и есть та же самая асинхронность, только с поддержкой в языке вместо построения абстракций только на уровне библиотек. В том плане, что можно вообразить гипотетический транслятор такого кода в классический асинхронный код и его логика работы будет весьма однозначной.
Поглядел в реализацию CompletableFuture.delayedExecutor()
- думал увижу что оно неблокирующе работает через механизмы epoll ОС, наподобие тому как оно устроено с сокетами/фаловыми опреациями...
Но оказалось все банально: всего лишь скедулим ретрай на экзекуторе как runnable, типа как executor.submit(...)
и естественно, имея под экзекутором очередь. Так что да - неблокирующе, но никакой магии господа, расходимся... я такие ретраи и раньше сам писал, до того как появился CompletableFuture
Неблокирующий повтор (retry) в Java и проект Loom