Обновить

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

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

Посмотрел результаты и код бенчмарка. Подозреваю, что бенчмарки все-таки протестировали время инициализации 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», — а выяснилось, что с тех пор, как я в последний раз заглядывал в документацию, — многое изменилось :)

Cloudflare почему-то свои unwrap не ловят , наверное тоже не знают.

Проблема-то не в том, чтобы поймать панику, проблема в том, чтобы поймать её в правильном месте.

У 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

Вы это серьёзно спрашивали в комментарии к тексту, в котором есть вот такой абзац:

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

Actix и его меньшие собраться написаны людьми, которые никогда в глаза не видели правильно реализованной акторной модели. Линки, мониторы, trap exists, cleanup on exit guarantees, деревья супервизоров, бесплатная кластеризация (не доделано, но там три часа разработки осталось), абстракции gen_server и gen_statem (!), корректная отработка паники в акторах, наконец. Да, и динамические сообщения, потому что акторы должны уметь хорошо работать в коллективе, где не всё написано на расте.

Вы спрашивали про свежие идеи? — Их нет. Всё это 40 лет назад придумал Джо, в честь которого и названа библиотека. Как и во многом другом, растаманам катастрофически не хватило эрудиции, и они изобрели свой велосипед, кривой и с одной педалью. Я постарался этот изъян поправить, но, как мы видим, вы даже не понимаете, в чем разница (тут просто: если не понимаете, вам противопоказано пользоваться акторной моделью в принципе).

вы даже не понимаете, в чем разница

так он буквально с этого вопроса и начал

В тот момент я еще надеялся на лучшее, и даже продублировал ответ на этот вопрос, скопипастив его из текста выше.

Там был вопрос об отличиях actix от моей реализации, мой последний пассаж — про непонимание, в чем отличие actix от эрланговской реализации. Это разные уровни непонимания.

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

А dyn в асинхронный трейтах тоже нативно поддерживается? Автору-то нужно чтобы конструкция Box<dyn Actor> работала.

Скорее всего, для динамик диспатча

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

Публикации