Обновить

Комментарии 26

Спасибо за статью! У меня появилось желание изучить тему акторов поподробнее, выглядит интересно.

Посмотрел результаты и код бенчмарка. Подозреваю, что бенчмарки все-таки протестировали время инициализации runtime (tokio vs actix). Выглядит так, что 10, 100, 1000 сообщений не достаточно для того, чтобы увидеть заметный результат.

Да бенчмарки никогда ничего из реального мира эмулировать не могут, только показать бинарное значение «на глаз»: годится / надо доработать. Меня результат устроил. Отдохну и допишу бенчмарки на миллионах сообщений, но сомневаюсь, что что-то прям изменится: узким звеном акторной модели были есть и будут хендлеры сообщений (читай: mailbox).

tokio vs actix

Не очень понял. Actix не переизобретал велосипед, там тоже токио под капотом.

Все-таки на маленьких значениях не видно разницы, т.к. в результатах не видно кратного увеличения времени при кратном увеличении количества сообщений. Если добавить побольше вариантов (10k, 100k, 1kk, 10kk), то вырисовывается другая картина:

Это не критика библиотеки, скорее замечение к тому, что бенчмарк не показательный получился, т.к. значения по большей степени константные получились. А уже на таких результатах можно по flamegraph найти горячие места и пооптимизировать.

Спасибо!

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

Да, я с вами полностью согласен, что здесь скорее бенчмарк в вакууме, чем тест реальной производительности. НО, я подчеркну, что бенчмарк все-таки хоть что-то должен показывать. Когда он показывает ~3 мс для 10, 100, 1000 вызовов функции, стоит задуматься, нужен ли такой бенчмарк. А когда он показывает 3 мс, 30 мс и 300 мс (если линейная асимптотика), то с этим уже проще работать, так как можно по flamegraph искать горячие точки и делать оптимизации константы или даже асимптотики.

В данной ситуации 3мс — это хорошее число. Оно сопоставимо с проверенной в боях библиотекой, и оно «правдоподобно». Этого на данной стадии достаточно.

Конечно, это не нужно называть «бенчмарк», это нужно называть «PoC», но смысл от этого не меняется; кроме того, мне понравилось, что мой код без единого онапиливания показывает результат не хуже асинкса, и я, конечно, похвастался :)

Век живи - век учи новые языки. Мне вот понадобился недавно язык с goto. Искал-искал, а нашел, к своему стыду, FreeBasic. И залип. А в нем и goto и классы и namespaces и Clib и еще куча. Всего. Понятно, что писать на нем ничего серьезного не планирую за пределами текущей задачи, но очень впечатлило.

Я не «учу» новые языки, я просто взял поиграться еще один из хайповых. Тут как с человеческими языками: когда свободно говоришь на полутора десятках из всех возможных языковых групп — на уровень C1 в еще одном нужно пару дней.

понадобился недавно язык с goto

А что не так с си и паскалем?

Мне вот понадобился недавно язык с goto. Искал-искал

C# язык в котором есть практически все, в том числе goto

Выглядит довольно неплохо, хотя к содержимому репы вопросы.

  • Ссылка на примеры из статьи ведёт на 404.

  • По канону в расте можно завести папочки example, tests и benchmarks, чтобы складировать туда соответствующие компоненты и делать штуки типа

    cargo run --example counter
    cargo test 
    cargo bench
  • не очень понятно зачем боксировать строки, когда можно завести обычный enum - благодатный и довольно маленький тип, представляющий из себя почти честные алгебраические типы, ещё и опечататься не даст. Ну, а если хочется по сети строку передавать, то просто делать сериализацию каким-нибудь serde

enum Commands {
  Increment(n: i32),
  Get,
  Stop,
};
/* */
match *cmd {
  Increment(n) =>  { 
    self.counter += n; 
    log(ctx, "Count changed {} to {}", n, self.count );
  }
  Get => log(ctx, "Current count {}", self.count),
  Stop => {
    log(ctx, "Stopping counter");
    ctx.stop(ExitReason::Normal);
  }
}

к содержимому репы вопросы

Ватсон просто без трубки уже не может, я прохожу уровень «макросы», поэтому репа уже триста раз модифицировалась, ща поправлю. Папочки есть, просто они отъехали в подпапочку.

зачем боксировать строки

Так там теоретически может быть

pub type Message = Box<dyn Any + Send + 'static>;

Строки — это же пример просто.

Эх

Я помню, что ещё летом обещал переписать что-то интересное с эрланг/эликсир на раст. Но времени нет совсем, сорян.

Да я вон за неполный трудовой день основную (козырную) часть эрланга переписал. И даже конечные автоматы снова по уму сделал: https://github.com/am-kantox/joerl/blob/main/joerl/examples/document_workflow.rs#L35-L50

Итак, я написал библиотеку, которая позволит эрлангистам проще вкатываться в раст.

Так оно не страшно, самое неудобное это async. Обмазывать код Send/arc. Когда лайфтам инференсом не выводит - боль. Ну и библиотеки внешние должны быть с поддержкой async. Еще не придумали как одноцветные функуции сделать .
Обработка ошибок отдельная тема, её прям со старта планировать надо.

Акторная модель притворяется краденой из эрланга, с примитивами GenServer и GenStatem, с деревьями супервизоров

Насколько понимаю, отбрабатывать panic/unwrap сейчас невозможно и сервер схлопывается. Интересно посмотреть, как может развиваться remote_actor. Rust/tokio склоняют делать один большой монолит.

Еще не придумали как одноцветные функуции сделать.

Кто не придумал? Что значит, «сделать»?

её [обработку ошибок] прям со старта планировать надо.

Кому надо? Зачем надо?

отбрабатывать panic/unwrap

С паникой я разберусь, конечно.

интересно посмотреть, как может развиваться remote_actor

Куда развиваться? Зачем ему развиваться? Вспоминается КВН: «—Слышал, Бузова развелась? — А она что, развивалась?»

Еще не придумали как одноцветные функуции сделать.
Кто не придумал? Что значит, «сделать»?

Имеется ввиду function coloring. Нельзя подключить библиотеку которую написали в синхронном стиле и наоборот. Есть даже отдельная реализация стандартной библиотеки async-std. В Erlang нет такого разделения, просто пишешь линейный код и не заморачиваешься.

её [обработку ошибок] прям со старта планировать надо.
Кому надо? Зачем надо?

Ну как пользователь свои типы ошибок прокинет, если разрешается использовать только ActorError, то окай.

интересно посмотреть, как может развиваться remote_actor
Куда развиваться? Зачем ему развиваться? Вспоминается КВН: «—Слышал, Бузова развелась? — А она что, развивалась?»

1. Transport Layer

2. Serialization

3. Node Discovery

4. Location Transparency

5. Fault Tolerance

6. Performance Optimizations

Этож эпичекий обьем работы, целая экосистема, а не простой crate.

Я знаю, в принципе, что такое function coloring, но передо мной именно эта проблема не стоит, от имплементации акторов ничкего не зависит, насколько я могу судить.

свои типы ошибок

Зачем? Кроме того, сделать ActorError поумнее можно в любой момент.

эпичекий обьем работы, целая экосистема, а не простой crate

И да, и нет.

Node Discovery и Serialization я делать [пока] не буду, потому что это и в OTP сделано через жопу, и люди через одного переписывают epmd.

Location Transparency, Transport Layer — я знаю, как сделать, и скоро сделаю.

Fault Tolerance уже есть.

Performance — ну это вообще сейчас тридцать пятая проблема же.

Панику я отработал, как в эрланге, fwiw.

:thumbup:

У меня устарешвая информация, catch_unwind уже стабилизировали. Cloudflare почему-то свои unwrap не ловят , наверное тоже не знают.

У меня было сходное ощущение, когда я завернул на PR Enum.sum/2 в эликсире с комментарием «галлюцинации ллмки надо проверять, нет такой функции, используйте Enum.reduce/3», — а выяснилось, что с тех пор, как я в последний раз заглядывал в документацию, — многое изменилось :)

У Erlang/OTP есть огромное преимущество, которое пока смогла повторить только Akka - простая и удобная кластеризация.

У Erlang/OTP есть огромное преимущество […]

Не может быть!

В примерах есть distributed_chat.rs, который уже готов к кластеру. Писать свой epmd я не [пока] собираюсь, потому что я и для OTP писал свой, а значит — нужен только протокол, дальше — сами. Всё остальное готово и работает (кроме прозрачной трансляции пидов, но это на три часа работы и в приоритете).

А почему Ray в python и orleans в .net неудобные для кластеризации?

А чем это отличается от https://github.com/actix/actix? Ну кроме того что зачем-то убрали строгую типизацию сообщений акторов и сделали все на даункастах, что довольно спорно с точки зрения идиоматичного раста

Названием.

Ну я это серьезно спрашивал, может какие-то идеи свежие есть, концепции, может он для эмбеддет подходит или еще что-то. Потому что акторных фреймворков на расте уже примерно 300 штук написано и действительно интересно зачем нужен 301-й

https://crates.io/search?q=actor framework

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации