SObjectizer 5.5.19
От: so5team https://stiffstream.com
Дата: 11.05.17 09:08
Оценка: 5 (1)
Сегодня мы официально выкатили очередную версию SObjectizer-а -- 5.5.19. В этой версии реализованы две большие фичи, которые казались немыслимыми еще совсем недавно.

Во-первых, добавлена возможность запускать SObjectizer в однопоточном режиме. Т.е. теперь можно написать приложение на акторах так, что все акторы и вся вспомогательная кухня самого SObjectizer-а будут работать на одной единственной рабочей нити. Это может пригодиться при написании простых приложений, в которых наличие акторов может быть выгодно (для упрощения логики), а вот создание нескольких рабочих потоков -- это уже оверкилл. Например, если маленькая программка должна собирать какую-то информацию и время от времени публиковать ее через MQTT. Или, скажем, при написании своей хитрой версии traceroute. Вот маленькая демонстрация того, к чему все это может прийти в пределе: тривиальный http-сервер для асинхронной обработки запросов на базе SObjectizer и restinio.

Во-вторых, добавлена возможность отсылки мутабельных сообщений. Поскольку ноги у SO-5 растут из модели Publish/Subscribe, в которой взаимодействие идет в режиме 1:N, все сообщения в SO-5 изначально были иммутабельными. В большинстве случаев это упрощало жизнь, но мешало в тех ситуациях, когда нужно было, например, построить обработку данных в режиме конвейера: один агент модифицировал данные и передавал их следующему в конвейере, при этом взаимодействие в конвейере всегда идет в режиме 1:1. В итоге в версии 5.5.19 добавлена поддержка мутабельных сообщений с обеспечением гарантии того, что мутабельное сообщение будет доставлено не более чем одному получателю. Подробнее все это показано в новой презентации из серии "Dive into SObjectizer-5.5". Кстати говоря, данная фича появилась после общения в кулуарах на C++ Russua 2017.

Все изменения в 5.5.19 описаны здесь.

Загрузить новую версию можно либо в виде архива с SourceForge, либо из svn-репозитория проекта, либо из зеркала на GitHub.

Между релизами 5.5.18 и 5.5.19 прошло довольно много времени, хотя на то были объективные причины. Надеемся, что работа над следующей версией, 5.5.20, пойдет быстрее и мы сможем выкатить ее в конце лета 2017-го.

Для будущей версии 5.5.20 у нас есть несколько своих идей, но в этом плане мы полностью открыты и готовы выслушать любые замечания и предложения. Так что, если кто-нибудь расскажет, что он хотел бы видеть в SObjectizer или, напротив, чего бы не хотел, то мы постараемся учесть это в своей работе. Опыт реализации таких фич, как отказ от дополнительного пространства имен so_5::rt, приоритеты агентов, иерархические конечные автоматы и мутабельные сообщения показывает, что это более чем возможно.

ЗЫ. Старую тему с анонсами SO-5 решил не поднимать, т.к. было это уже слишком давно. Для, кто не в курсе, что такое SObjectizer -- это один из немногих живых и развивающихся OpenSource кросс-платформенных фреймворков для C++, которые дают разработчику возможность использовать Actor Model (в случае с SO-5 сюда добавляются еще и Pub/Sub, и CSP).
Re: SObjectizer 5.5.19
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 11.05.17 09:24
Оценка:
Здравствуйте, so5team, Вы писали:

S>Во-первых, добавлена возможность запускать SObjectizer в однопоточном режиме. Т.е. теперь можно написать приложение на акторах так, что все акторы и вся вспомогательная кухня самого SObjectizer-а будут работать на одной единственной рабочей нити. Это может пригодиться при написании простых приложений, в которых наличие акторов может быть выгодно (для упрощения логики), а вот создание нескольких рабочих потоков -- это уже оверкилл. Например, если маленькая программка должна собирать какую-то информацию и время от времени публиковать ее через MQTT. Или, скажем, при написании своей хитрой версии traceroute. Вот маленькая демонстрация того, к чему все это может прийти в пределе: тривиальный http-сервер для асинхронной обработки запросов на базе SObjectizer и restinio.


У меня практический вопрос. В одной программе мне нужен был простенький http server, однопоточный тоже подойдёт. Я взял готовый как раз из boost::asio. Он не такой маленький, как в твоём примере, но я его и не писал — взял готовый.
Раз вы приводите такой пример, также используете boost::asio, то было бы неплохо сравнить две реализации. Чем ваш лучше? Лично мне было бы интересно.
Re[2]: SObjectizer 5.5.19
От: so5team https://stiffstream.com
Дата: 11.05.17 10:56
Оценка: 8 (1)
Здравствуйте, Nuzhny, Вы писали:

N>Здравствуйте, so5team, Вы писали:


N>У меня практический вопрос. В одной программе мне нужен был простенький http server, однопоточный тоже подойдёт. Я взял готовый как раз из boost::asio. Он не такой маленький, как в твоём примере, но я его и не писал — взял готовый.

N>Раз вы приводите такой пример, также используете boost::asio, то было бы неплохо сравнить две реализации. Чем ваш лучше? Лично мне было бы интересно.

Все зависит от критерия, которым сравнивать.

Если ситуация такова, что заранее определена логика того, что нужно отвечать на конкретный запрос, то разница между:
1. взять набор кода из примера asio и изменить в нем обработчик (суть одну функцию);
2. взять набор кода sobjectizer+restinio и изменить в нем тоже только обработчик;
невелика, и зависит не от функциональности sobjectizer+restinio, а скорее от удобства сборки, размером бинарников, скорости компиляции.

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

request_handler_.handle_request(request_, reply_); // Вызов обработчика.
do_write(); // Ожидается, что ответ уже готов.


А теперь представим, что ответ нельзя получить сразу, например, нужно обратиться к какому-то асинхронному API, и вот тут возможны два основных варианта:
1. обработчик залипает на некоторое время, пока не будут готовы данные для ответа;
2. обработчик должен уметь работать асинхронно: получив запрос, взять его в обработку, и освободить нить исполнения для обработки других соединений и их обработчиков, а когда данные для ответа будут получены надо иметь возможность собрать и отправить ответ.

C примером на asio легко применить первый вариант, а вот второй уже надо будет хорошенько переделывать логику работы класса connection и обработчика. В примере на sobjectizer+restinio второй вариант сразу в наличии и есть. В примере просто продемонстрирован вход к SObjectizer через http, а SObjectizer это асинхронность в полный рост, но это в примере полностью, конечно, не раскрыто.

Еще можно посмотреть на синтаксические отличия. В RESTinio удобнее работать с заголовками и удобнее строить ответ. Еще вопрос на сколько проверенный http-парсер в asioпримере, в RESTinio используется
nodejs/http-parser.
Re: SObjectizer 5.5.19
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 11.05.17 11:36
Оценка:
Здравствуйте, so5team, Вы писали:

S>Сегодня мы официально выкатили очередную версию SObjectizer-а -- 5.5.19. В этой версии реализованы две большие фичи, которые казались немыслимыми еще совсем недавно.


Хотелось бы сделать одно предложение по документации. С ней, в принципе, всё прекрасно, да и ты на вопросы отвечаешь, но (для корпоративного мира) не хватает такой мелочи как "успешные истории внедрения". Реально, сильно помогло бы ответить на довольно формальный вопрос "а почему нужно их взять?"
Re[2]: SObjectizer 5.5.19
От: so5team https://stiffstream.com
Дата: 11.05.17 11:42
Оценка:
Здравствуйте, kaa.python, Вы писали:

KP>Хотелось бы сделать одно предложение по документации. С ней, в принципе, всё прекрасно, да и ты на вопросы отвечаешь, но (для корпоративного мира) не хватает такой мелочи как "успешные истории внедрения". Реально, сильно помогло бы ответить на довольно формальный вопрос "а почему нужно их взять?"


Нужно будет пообщаться с нашими прошлыми работодателями. Есть некоторые сомнения в том, что там захотят открывать подробности реализации использующих SObjectizer проектов. Если получится, сделаем что-то вроде подборки success stories.
Re[3]: SObjectizer 5.5.19
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 11.05.17 11:49
Оценка:
Здравствуйте, so5team, Вы писали:

S>C примером на asio легко применить первый вариант, а вот второй уже надо будет хорошенько переделывать логику работы класса connection и обработчика. В примере на sobjectizer+restinio второй вариант сразу в наличии и есть. В примере просто продемонстрирован вход к SObjectizer через http, а SObjectizer это асинхронность в полный рост, но это в примере полностью, конечно, не раскрыто.


S>Еще можно посмотреть на синтаксические отличия. В RESTinio удобнее работать с заголовками и удобнее строить ответ. Еще вопрос на сколько проверенный http-парсер в asioпримере, в RESTinio используется

S>nodejs/http-parser.

Это уже интересно. Но, конечно, полноценный пример пощупать руками хотелось бы, чтобы делать выводы.
В boost::asio парсер используется самописный, он часть примера.
Re: SObjectizer 5.5.19
От: niXman Ниоткуда https://github.com/niXman
Дата: 11.05.17 12:39
Оценка:
Здравствуйте, so5team, Вы писали:

S>Во-первых, добавлена возможность запускать SObjectizer в однопоточном режиме. Т.е. теперь можно написать приложение на акторах так, что все акторы и вся вспомогательная кухня самого SObjectizer-а будут работать на одной единственной рабочей нити.


т.е. SObjectizer не создает вообще ни одного дополнительного потока?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: SObjectizer 5.5.19
От: so5team https://stiffstream.com
Дата: 11.05.17 12:43
Оценка: +1
Здравствуйте, niXman, Вы писали:

S>>Во-первых, добавлена возможность запускать SObjectizer в однопоточном режиме. Т.е. теперь можно написать приложение на акторах так, что все акторы и вся вспомогательная кухня самого SObjectizer-а будут работать на одной единственной рабочей нити.


X>т.е. SObjectizer не создает вообще ни одного дополнительного потока?


Да, может все делать только на том потоке, на котором его запустили. Здесь подробнее на эту тему.
Re: SObjectizer 5.5.19
От: YuriV  
Дата: 18.05.17 15:28
Оценка:
Здравствуйте, so5team, Вы писали:

S>Сегодня мы официально выкатили очередную версию SObjectizer-а -- 5.5.19. В этой версии реализованы две большие фичи, которые казались немыслимыми еще совсем недавно.


А когда появиться so_5_extra(интересует именно интеграция с asio)?
Re[2]: SObjectizer 5.5.19
От: so5team https://stiffstream.com
Дата: 18.05.17 18:04
Оценка:
Здравствуйте, YuriV, Вы писали:

S>>Сегодня мы официально выкатили очередную версию SObjectizer-а -- 5.5.19. В этой версии реализованы две большие фичи, которые казались немыслимыми еще совсем недавно.


YV>А когда появиться so_5_extra(интересует именно интеграция с asio)?


Судя по всему, где-то в начале или середине июня.
Re: SObjectizer 5.5.19
От: so5team https://stiffstream.com
Дата: 07.06.17 08:22
Оценка:
На случай, если кто-то захочет высказать свое мнение о том, чего ему лично не хватает в SObjectizer: http://eao197.blogspot.com/2017/06/progc-erlang-style-sobjectizer.html

Ну или если хотелось бы чего-то, что уже есть, но сделанного по-другому, то нам бы так же было бы интересно выслушать стороннее мнение. Есть далеко не нулевые шансы, что мы прислушаемся
Re: so_5_extra-1.0.0 и so-5.5.19.2
От: so5team https://stiffstream.com
Дата: 26.06.17 13:27
Оценка:
Мы выпустили первую версию своего нового проекта поверх SObjectizer -- so_5_extra версии 1.0.0.

В этой версии в so_5_extra доступны:

Исходники можно взять либо из репозитория, либо загрузить из соответствующего раздела.

Документацию по проекту можно найти в Wiki. Если из документации чего-то не понятно или что-то в ней не описано, то не сочтите за труд, дайте нам знать. Улучшим, расширим и углубим

Проект header-only. Если захочется собрать тесты и примеры самостоятельно, то придется воспользоваться Ruby и Mxx_ru. Зависимости так же подтягиваются через MxxRu::externals. Но в секции Files есть архивы с именами вида so_5_extra-1.0.0-full.tar.xz, в которых уже все зависимости присутствуют. Поэтому можно брать *-full.tar.xz архив, распаковывать, прописывать в INCLUDE путь к so_5_extra-1.0.0/dev и пробовать.

Работоспособность проверялась под Linux-ом (gcc 5.4 и 7.1, clang 3.7 и 4.8) и Windows (gcc 5.2-7.1, VC++ 14.0 и 15.0). На всякий случай выставлять -Werror при работе с so_5_extra не советуем, т.к. и gcc, и clang очень сильно ругаются на потроха Asio.

В планах у нас добавление еще нескольких фич в so_5_extra. Следующие версии будут выходить по мере добавления новых фич. В том числе в планах и simple_mtsafe-инфраструктура для Asio, но приоритет у этой задачи не самый высокий. Если кому-то нужна thread-safe реализация Asio-инфраструктуры для SO-5, то дайте знать. Постараемся повысить приоритет.

Обращаем внимание, что so_5_extra распространяется под двойной лицензией: GNU Affero GPL для OpenSource применения, и коммерческая лицензия для использования в закрытых проектах. Если кому-то интересна коммерческая лицензия, то пишите на info at stiffstream dot com, там цена вопроса порядка $40 за одного разработчика в год.

Попутно мы сделали SObjectizer-5.5.19.2, в который вошло несколько фич, необходимых для реализации so_5_extra. Дистрибутивы SObjectizer лежат там же, где и обычно.
Re[2]: SObjectizer 5.5.19
От: so5team https://stiffstream.com
Дата: 26.06.17 13:39
Оценка:
Здравствуйте, YuriV, Вы писали:

YV>А когда появиться so_5_extra(интересует именно интеграция с asio)?


В начале-середине июня не получилось, только сейчас выкатили
Автор: so5team
Дата: 26.06.17
.
Re: Свежая статья (разбор примера machine_control)
От: so5team https://stiffstream.com
Дата: 04.07.17 07:20
Оценка: 34 (3)
Извиняемся за ссылку на Хабр, но мы сделали большую статью, в которой подробно рассматривается намного более сложный пример, чем абстрактные и бесполезные на практике ping-pong-и (коими принято меряться в разговорах про акторные фреймворки): Имитируем управление устройствами с помощью акторов
Re[2]: Свежая статья (разбор примера machine_control)
От: dr. Acula Украина  
Дата: 08.08.17 19:11
Оценка:
Здравствуйте, so5team, Вы писали:

S>Извиняемся за ссылку на Хабр, но мы сделали большую статью, в которой подробно рассматривается намного более сложный пример, чем абстрактные и бесполезные на практике ping-pong-и (коими принято меряться в разговорах про акторные фреймворки): Имитируем управление устройствами с помощью акторов


Linux.
Созрели до использования в продакшене, смотрели на CAF, но как-то займно слишком у ребят всё.

Есть актор(ы), который висит на asio сокете, при успешном accept — создаётся дочерний актор и в него уходит свежий сокет из которого потом происходит чтение/запись.
При ошибке сокета актор сам себя удаляет из кооперации.

Дочерних актров планируется порядка сотен.
Работать, наврено, будут на thread_pool с размером 8-16.
Коммуникация не очень активная. В основном будут записи в сокет, которые инициирует сервер.

Так вот вопрос.
Есть ликакие-то подводные камни, на которые следует обратить внимание при совместной работе SO и boost::asio?
Re[3]: Свежая статья (разбор примера machine_control)
От: so5team https://stiffstream.com
Дата: 09.08.17 07:59
Оценка: 6 (1)
Здравствуйте, dr. Acula, Вы писали:

DA>Так вот вопрос.

DA>Есть ликакие-то подводные камни, на которые следует обратить внимание при совместной работе SO и boost::asio?

Главный камень -- это то, что для Asio нужен свой набор рабочих потоков, на которых будет крутиться asio::io_service::run(), а SO нужен свой набор рабочих потоков, на которых будут работать SO-шные агенты. И просто так эти наборы рабочих потоков не подружить.

У нас сейчас есть реализация однопоточного SO, в которой Asio и SO работают на одном потоке (фактически, там работает asio::io_service::run(), а SO пользуется средствами Asio для диспетчеризации своих событий). Но она именно что однопоточная, реализации для совместной работы Asio и SO на thread_pool-е пока еще нет.

Но даже если Asio и SO используют один и тот же рабочий контекст, все равно идея об вызове Asio-шных accept/read/write из агентов не выглядит разумной. Дело в том, что если read/write синхронные и блокирующие, то агент просто заблокирует рабочую нить и это не позволит другим агентам использовать эту рабочую нить. Можно попробовать использовать async_read/async_write, но тогда нужно будет обвешивать агентов stand-ами, дабы не получилось, что Asio дергает коллбэк для async-операции на одной рабочей нити, а SO дергает событие этого же агента на другой.

А почему вы решили, что вам здесь нужны акторы? По вашему описанию создается ощущение, что вам достаточно родных средств самого Asio. Так, у вас будет какой-то объект, реагирующий на успешные accept-ы. Он создает другие объекты, которые получают готовый сокет и выполняют асинхронные I/O операции посредством вызова async_read/async_write. Что-то вроде:
class connection_handler final : public std::enable_shared_from_this<connection_handler> {
  asio::tcp::socket socket_;
  asio::io_service::strand strand_;
  ...
  void on_receive(const asio::error_code & ec, std::size_t bytes_received) {
    if(!ec) {
      ... // Какая-то обработка полученных данных.
      // Запись ответа.
      socket_.async_write(some_outgoing_buffer(),
          strand_.wrap(std::bind(connection_handler::on_send, shared_from_this(), _1, _2)));
    }
    else { /* Обработка ошибки */ }
  }
  void on_send(const asio::error_code & ec, std::size_t bytes_sent) {
    if(!ec) {
      ... // Какая-то реакция на успешную запись.
    }
    else { /* Обработка ошибки */ }
  }
  ...
};

Есть ощущение, что вот такого использования Asio вам может хватить и без привлечения какого-либо акторного фреймворка.

Если же все-таки нужны кроме обработчиков I/O операций еще и акторы, то на данный момент единственный способ сделать такое -- это иметь отдельные объекты для I/O операций и отдельных агентов для выполнения прикладной логики. Так, I/O-объекты будут вычитывать данные из сокетов и пересылать эти данные агентам. Агенты будут обрабатывать полученные от I/O-объектов данные, выполнять какую-то прикладную работу и будут генерировать ответные данные для отсылки. Отсылку же будут выполнять I/O-объекты. Может получиться что-то вроде:
// Сообщение для передачи прочитанных данных прикладному агенту.
struct data_read final : public so_5::message_t {
  std::vector<std::uint8_t> data_;
  std::shared_ptr<connection_handler> io_handler_;
  data_read(std::vector<std::uint8_t> data, std::shared_ptr<connection_handler> io_handler)
    : data_(std::move(data)), io_handler_(std::move(io_handler))
  {}
};

// Объект, который обрабатывает сокет.
class connection_handler final : public std::enable_shared_from_this<connection_handler> {
  asio::tcp::socket socket_;
  asio::io_service::strand strand_;
  ...
  so_5::mbox_t receiver_; // Адрес агента, которому нужно отсылать прочитанные данные.
  ...
  std::vector<std::uint8_t> data_; // Буфер-приемник для чтения данных.
  ...
  void start() {
    // Начинаем читать входящие данные.
    data_.resize(some_appropriate_size);
    socket_.async_read_some(asio::buffer(data_),
      strand_.wrap(std::bind(connection_handler::on_receive, shared_from_this(), _1, _2)));
    ...
  }
  void on_receive(const asio::error_code & ec, std::size_t bytes_received) {
    if(!ec) {
      // Отсылаем данные агенту для обработки.
      data_.resize(bytes_received);
      so_5::send<data_read>(receiver_, std::move(data_), shared_from_this());
    }
    else { /* Обработка ошибки */ }
  }
  ...
};

// Агент, который получает входящие данные.
class data_handler final : public so_5::agent_t {
public:
  data_handler(context_t ctx, ...) : so_5::agent_t(std::move(ctx)), ... {
    // Создаем подписку на прочитанные данные.
    so_subscribe_self().event(data_handler::on_data_read);
    ...
  }
  ...
private:
  void on_data_read(mhood_t<data_read> cmd) {
    ...
  }
};


В этом случае вообще нет надобности создавать thread_pool для Asio, достаточно будет и одной рабочей нити, на которой будет работать asio::io_service::run(). Ну а SO-шных агентов можно будет распределить по тем контекстам, которые им нужны. Тут от специфики задачи зависит.
Re[4]: Свежая статья (разбор примера machine_control)
От: dr. Acula Украина  
Дата: 09.08.17 08:41
Оценка:
S>Если же все-таки нужны кроме обработчиков I/O операций еще и акторы, то на данный момент единственный способ сделать такое -- это иметь отдельные объекты для I/O операций и отдельных агентов для выполнения прикладной логики. Так, I/O-объекты будут вычитывать данные из сокетов и пересылать эти данные агентам. Агенты будут обрабатывать полученные от I/O-объектов данные, выполнять какую-то прикладную работу и будут генерировать ответные данные для отсылки. Отсылку же будут выполнять I/O-объекты. Может получиться что-то вроде:

С отправкой агентам — все прозрачно, so_5::send<...> рещает проблему.
А как в обратную сторону передавать что-то I/O потокам в такой архитектуре?
Фактически идея — TCP/UDP прокси с агентами внутри для кеширования и другой логики.
Отредактировано 09.08.2017 8:47 dr. Acula . Предыдущая версия .
Re[5]: Свежая статья (разбор примера machine_control)
От: so5team https://stiffstream.com
Дата: 09.08.17 09:01
Оценка: 6 (1)
Здравствуйте, dr. Acula, Вы писали:

DA>С отправкой агентам — все прозрачно, so_5::send<...> рещает проблему.

DA>А как в обратную сторону передавать что-то I/O потокам в такой архитектуре?

Можно сделать как-то так (набросок): в сообщении data_read передается умный указатель на connection_handler. Поэтому у connection_handler-а можно дергать методы. Для того, чтобы инициировать запись со стороны агента в публичный интерфейс connection_handler добавляется вспомогательный метод initiate_write. Этот initiate_write задействует Asio-шный post для того, чтобы инициировать запись в сокет на контексте одного из I/O-потоков.

Получится, что агент дергает публичный метод connection_handler::initiate_write через умный указатель из сообщения data_read. Внутри initiate_write инициируется отложенная запись на контексте рабочих потоков Asio (т.е. что-то аналогичное so_5::send).

Тут фокус в том, чтобы не протухла ссылка на буфер с исходящими данными. Поэтому в наброске ниже я добавил в connection_handler поле outgoing_data_, в которое исходящие данные перемещаются перед записью. Если же возможна ситуация, когда агент может инициировать несколько send-ов (при этом следующий send может возникнуть еще до того, как закончится предыдущий), то нужно будет сделать какую-то более хитрую схему. Но это вряд ли будет представлять проблему. Так, initiate_write может постить через asio::post не вызов socket_.async_send, а операцию добавления очередного буфера в список буферов с исходящими данными. Тут большой простор для фантазии.

// Класс, который обрабатывает соединение.
class connection_handler final : public std::enable_shared_from_this<connection_handler> {
  asio::tcp::socket socket_;
  ...
  std::vector<std::uint8_t> outgoing_data_;
public:
  void initiate_write(std::vector<std::uint8_t> data) {
    outgoing_data_ = std::move(data);
    asio::post(socket_.get_executor(),
      [self=shared_from_this()] {
        self->socket_.async_send(
          asio::buffer(self->outgoing_data_),
          strand_.wrap(std::bind(connection_handler::on_sent, self, _1, _2)));
      });
  }
  ...
};
...
// Сообщение для передачи прочитанных данных прикладному агенту.
struct data_read final : public so_5::message_t {
  std::vector<std::uint8_t> data_;
  std::shared_ptr<connection_handler> io_handler_;
  data_read(std::vector<std::uint8_t> data, std::shared_ptr<connection_handler> io_handler)
    : data_(std::move(data)), io_handler_(std::move(io_handler))
  {}
};
...
// Класс агента, который обрабатывает данные.
class data_handler final : public so_5::agent_t {
  ...
private:
  void on_data_read(mhood_t<data_read> cmd) {
    ... // Какие-то действия над прочитанными данными.
    // Здесь нам нужно записать что-то в ответ.
    std::vector<std::uint8_t> outgoing_data{ ... };
    cmd->io_handler_->initiate_write(std::move(outgoing_data));
  }
};
Re: Новая статья (про акторов+SEDA-way)
От: so5team https://stiffstream.com
Дата: 10.08.17 08:57
Оценка: 4 (1)
Очередная статья, написанная на основе опыта работы с моделью акторов. На этот раз без какой-то жесткой привязки к C++ и SObjectizer-у. Так что, мы надеемся, она будет интересна большему кругу читателей: Объединяем акторов и SEDA-подход: зачем и как?
Re: Новая статья (про CSP-шные каналы)
От: so5team https://stiffstream.com
Дата: 31.08.17 11:41
Оценка: 4 (1)
Мы попытались привести пример того, как SObjectizer упрощает разработку многопоточных программ даже без использования агентов, только за счет применения mchain-ов: Многопоточность в C++ и SObjectizer с CSP-шными каналами, но совсем без акторов…
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.