Giter Site home page Giter Site logo

eao197 / so-5-5 Goto Github PK

View Code? Open in Web Editor NEW
88.0 10.0 7.0 4.9 MB

SObjectizer: it's all about in-process message dispatching!

Home Page: https://stiffstream.com/en/products/sobjectizer.html

License: Other

CMake 2.36% Ruby 5.02% C++ 92.53% Batchfile 0.01% Makefile 0.09%
c-plus-plus sobjectizer actor-model actors message-queue message-passing multithreading concurrency csp cpp

so-5-5's People

Contributors

eao197 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

so-5-5's Issues

[en] `so_5::message_t` is optional in some places, and mandatory in the others?

Hi,

If I define message user-defined struct, i.e.

struct timeout_initialize {
    actor_t actor;
    so_5::mbox_t mbox;
    timeout_initialize(actor_t actor_, const so_5::mbox_t& mbox_): actor{actor_}, mbox{mbox_}{}
};

it is still possible to send it via so_5::send<timeout_initialize>(...). However, when I try to send it via schedule_timer

so_environment().schedule_timer(
                std::make_unique< message::timeout_initialize >(m.actor, m.mbox ),
                so_direct_mbox(),
                std::chrono::milliseconds(200),
                std::chrono::milliseconds::zero()
    );

the compiler errors with :

../so_5/rt/h/message.hpp:655:18: error: static assertion failed: expected a type derived from the message_t
   static_assert( is_classical_message< Msg >::value,

If the timeout_initialize inherits from so_5::message_t, the error message disappears and everything looks fine.

However, it's a bit weird API-interface: messages, which I don't need send via schedule_timer can be user-defined types, but if they are delivered via schedule_timer, they have to be derived from so_5::message_t .

[en] so_5::deregister_coop_on_exception & exception requirements

Hi,

It is setup to handle exceptions via coop.set_exception_reaction(so_5::deregister_coop_on_exception);

When an child agent throws an arbitrary exception, not derived from std::except, it just terminates:

...
throw ("boom");
terminate called after throwing an instance of 'char const*'
[1]    18965 abort      ./syncspirit --log_level debug --config_file ../syncspirit.conf

However, when std::exception is thrown:

...
throw std::runtime_error("boom");

Then it is catch and behaves correctly

SObjectizer event exception caught: boom; cooperation: 'logger'
[2019-03-09 11:47:51.577 TID:140664060745472] Cooperation 'logger' will be deregistered due to unhandled exception 'boom' (/home/b/development/cpp/sync-spirit/lib/so-5-5/dev/so_5/rt/impl/process_unhandled_exception.cpp:189)

I think it is too strong assumption, that 3rd-party libraries will always throw something derived from std::except

PS. It is also terminates on throw new std::runtime_error("boom"). Of course, this is buggy/discouraged to throw new exception, but that's what I met in the others' code.

Unstable test _unit.test.layer.extra_layer_query

.../Sources/SObjectizer/dev/test/so_5/layer/extra_layer_query/main.cpp(91): unit test error: comparison failed: 'so_env.query_layer_noexcept< test_layer_t< 1 > >() == tl1' where
[
so_env.query_layer_noexcept< test_layer_t< 1 > >() is 0,
tl1 is 0x9901c0
]
Unit test 'check_1_3_exist' failed

Я пока еще не пытался углубляться, но срабатывает он не всегда.

[ru] На пути к SObjectizer-5.6

Мотивация

Работа над веткой 5.5 началась более 4.5 лет назад. В условиях, когда приходилось использовать компиляторы без вменяемой поддержки даже C++11, не говоря уже про C++14. Все это время SObjectizer-5.5 развивался во-первых, с серьезной оглядкой на старые C++ компиляторы и, во-вторых, с максимальным сохранением совместимости между версиями в рамках ветки 5.5. Кроме того, SObjectizer-5.5 унаследовал ряд проектных решений из еще более ранних версий SObjectizer-5.

В результате в реализации SObjectizer-5.5 накопились "косяки", которые были обусловлены как просчетами при проектировании, так и невозможностью использовать новые версии стандарта C++. Исправить эти косяки без нарушения совместимости между версиями не представляется возможным.

В условиях 2019-го года продолжать развитие ветки 5.5 с оглядкой как на ограниченное подмножество C++11, так и на совместимость с проектными решениями, принятыми 4.5 года назад не представляется более ни разумным, ни экономически оправданным.

Цель разработки SObjectizer-5.6

Целью разработки ветки 5.6 является устранение проблем ветки 5.5 при сохранении основных принципов работы SObjectizer-5, но без стремления обеспечить 100% совместимость с веткой 5.5.

Планируемые изменения в SObjectizer-5.6

Изъятие всего того, что в SObjectizer-5.5 было помечено как deprecated.

За более чем 4 года развития ветки 5.5 множество вещей было помечено как deprecated. Например, пространство имен so_5::rt или функция send_delayed_to_agent. Из-за сохранения совместимости все это еще присутствует в SObjectizer-е и, более того, работает.

Однако, пришло время избавить кодовую базу SObjectizer-а от этого старого хлама.

Каждый mbox будет содержать ссылку на SObjectizer Environment

В SObjectizer-5.5 через mbox нельзя получить ссылку на SObjectizer Environment, хотя это можно было бы сделать для MPSC-mbox-а. Тогда как через mchain ссылку на SObjectizer Environment получить можно. При этом mchain может трансформироваться в mbox, а из mbox доступа к Environment-у нет.

Если в mbox-е будет хранится ссылка на SObjectizer Environment, то получится сделать send_delayed и send_periodic унифицированными. Т.е. вызов send_delayed(mbox, pause, args) будет выглядеть так же, как и send_delayed(agent, pause, args).

Сокращение количества способов отослать сообщение

Сейчас в SObjectizer-5.5 по историческим причинам накопился ряд методов для отсылки сообщений (например, различные варианты deliver_message в классе abstract_message_box_t) и выполнения синхронных запросов. Здесь нужно навести порядок и оставить лишь самый необходимый минимум в классах abstract_message_box_t, environment_t, а также останется только ряд шаблонных функций send, send_delayed, send_periodic, request_value и request_future.

Сокращение количество разрешенных форматов обработчиков сообщений

Останется поддержка только двух следующих форматов:

ret_type event_handler(mhood_t<msg_type>); // for messages and signals.
ret_type event_handler(const mhood_t<msg_type> &); // for messages and signals.

Останутся только обычные агенты, ad-hoc агенты будут удалены

Практика показывает, что определить обычного агента, который выполняет какие-то простые действия, прямо "по месту" в современном C++ совсем не сложно. Поэтому затраты на поддержку ad-hoc агентов в SObjectizer-е не соответствуют той выгоде, которую ad-hoc агенты дают.

Будет изъята поддержка tuple_as_message

После того, как в SObjectizer-5.5 появилась возможность отсылки сообщений произвольных пользовательских типов (без необходимости наследования от so_5::message_t), надобность в функциональности tuple_as_message, фактически, отпала.

Будет устранено деление на публичные и приватные диспетчеры

Исторически в SObjectizer-е были только публичные диспетчеры. Затем были добавлены приватные диспетчеры, которые и рекомендуются к использованию. Поддержка и публичных, и приватных диспетчеров усложняет API SObjectizer-а и привносит дополнительные расходы на его развитие и сопровождение. Поэтому в SObjectizer-5.6 останутся только приватные диспетчеры.

Будет проведена чистка API

Будут удалены методы, которые дублируются и/или имеют потенциально опасный вид, например, принимают "голые" указатели.

Где будут жить исходники SObjectizer-5.6?

До сих пор исходники SObjectizer-а жили в Subversion репозитории на SourceForge с экспериментальным зеркалом на GitHub-е. Для SObjectizer-5.6 это уже будет не так.

Во-первых, скорость работы с Svn на SF.net в последнее время стала недостаточно хорошей. И сам Svn-репозиторий на SF.net время от времени оказывается недоступным.

Во-вторых, хотелось бы иметь более простую интеграцию с сервисами, вроде TravisCI, без процедуры зеркалирования куда-то Svn-репозитория.

В качестве основного варианта пока рассматривается разработка SO-5.6 непосредственно на GitHub-е (с именем вида https://github.com/Stiffstream/sobjectizer-5.6). Но кое-кто из разработчиков SObjectizer-а (например, eao197) не любит ни git, ни GitHub.

Поэтому есть альтернативный вариант -- Mercurial-репозиторий на BitBucket-е (с именем вида http://bitbucket.org/sobjectizerteam/sobjectizer-5.6). С зеркалом на GitHub. Благо Hg зеркалируется в git гораздо проще.

Решение по этому вопросу еще не принято.

Соответственно, сопутствующие проекты, т.к. timertt и so_5_extra, будут жить в отдельных репозиториях на том же самом хостинге, что и SObjectizer-5.6. Управление зависимостями будет построено на базе MxxRu::externals.

Где будет жить документация по SObjectizer-5.6?

Открытый пока вопрос. Есть три основных варианта.

  1. Размещение документации по новой версии в Wiki проекта на SourceForge. Чтобы вся документация была собрана в одном месте. Кроме того, в этом варианте проще писать новую документацию, т.к. можно переделывать старую.

  2. Размещение документации в Wiki того репозитория, в котором будут размещаться исходники SObjectizer-5.6.

  3. Размещение документации на сайте stiffstream.com, как это сейчас происходит, например, с документаций по RESTinio.

Какая версия стандарта C++ будет использоваться для разработки версии 5.6?

Есть большое желание сразу использовать C++17. И, соответственно, в качестве минимальных версий компиляторов рассматривать GCC 7, clang 6 и Visual C++ 15.9.3. Либо даже GCC 8, clang 7 и VC++ 15.9.3.

Требования к стандарту C++ можно уменьшить до C++14, но только в случае, если кто-то объяснит, почему это важно. Если никто не попросит о поддержке C++14, то ее и не будет.

С++11 не будет поддерживаться в принципе. Если вам это, действительно нужно, то рассмотрите, пожалуйста, вариант коммерческой поддержки SObjectizer-а.

Что по срокам?

Разработка SObjectizer-5.6, как предполагается, будет состоять из двух стадий.

На первой стадии происходит чистка исходного кода SObjectizer-а и формирование основной кодовой базы SObjectizer-5.6. Плюс адаптация уже написанной документации и учебных материалов к особенностям версии 5.6. Завершается эта стадия выпуском версии 5.6.0. Если все будет идти нормально, без форс-мажоров, то ожидать релиза 5.6.0 можно к концу февраля 2019-го.

Следующая стадия начнется после релиза версии 5.6.0. Она подразумевает расширение SObjectizer-5.6 новой функциональностью. Т.е. новые фичи будут добавляться не в SO-5.5, а в SO-5.6.

Какое время жизни планируется у SObjectizer-5.6?

Предположительно, SObjectizer-5.6 будет актуален до конца 2019-го года. Дальше мы пока не загадываем.

На развитие SObjectizer-5.6 прямое влияние будет оказывать его востребованность. Чем больше людей будет использовать SO-5.6 и будет высказывать заинтересованность в нем, тем дольше мы будет развивать ветку 5.6 обеспечивая максимально возможную совместимость между версиями внутри ветки, как это происходило с веткой 5.5.

Что будет дальше с SObjectizer-5.5?

Ничего.

До момента релиза SObjectizer-5.6.0 мы будет устранять найденные в SObjectizer-5.5 проблемы и выпускать обновления. После релиза версии 5.6.0 какое-либо развитие ветки 5.5 будет остановлено.

Если вам необходима дальнейшая поддержка SObjectizer-5.5, то вы можете обратиться к нам за коммерческой поддержкой.

Как вы можете повлиять на развитие SObjectizer-а?

Мы всегда прислушиваемся к пожеланиям наших пользователей. Поэтому если вы найдете возможность высказать свое мнение о том, каким вы видите SObjectizer-5.6, что вы хотели бы там иметь, чтобы вы из SObjectizer-а выбросили бы, устраивает ли вас использование стандарта C++17, напрягает ли вас хостинг проекта на BitBucket-е и т.д., то вы окажете нам существенную помощь в выборе вектора дальнейшего развития SObjectizer-а.

[en/ru] Event-handlers formats for SObjectizer-5.6

There is a topic in development of SObjectizer-5.6 where some feedback from SObjectizer's users (or just watchers) are required. I described this topic in a post in SObjectizer's Google group: Event-handler formats in SObjectizer-5.6. Please share you option if you have a time/desire. As reply in the Google group or even here.


При разработке SObjectizer-5.6 возникла тема, по которой хотелось бы получить обратную связь от пользователей SObjectizer-а или просто интересующихся. Тема описана в SObjectizer-овской Google-группе: Форматы обработчиков сообщений в SObjectizer-5.6. Пожалуйста, поделитесь своими соображениями, если у вас найдется время и желание. В виде ответа в Google-группе или прямо здесь.

Tabs

Please stop using tabs in source code. Tabs are hang-over from the 1960s when typists saved keystrokes and improved accuracy by use of the Tab key and tab stops. They were also used by computers to control IBM Selectric typewriters to aid printing forms. This was important because one never knew exactly where the printed form would end up on the paper until it arrived from the printer.

All modern editors allow programming the tab key to insert spaces, assisting in alignment and assuring all clients get the same layout.

Tab characters are a disaster in source code. The code becomes unreadable on some devices such as my console. They're also indistinguishable from spaces in my editor. Error diagnostics cannot correctly refer to column numbers since the tab stops are viewing-device dependent.

I use 2 character indents, which is the best format for books (which have small line widths), however 4 is acceptable. 3 is silly. 8 is way too much. 8 is the default on my console. My editor is fixed to 2.
Invariant layout is incompatible with use of tabs.

multiparameter messages

It was not bad to have it possible not to write your structure but to transfer a set of parameters in rune-time.

auto args0 = 0;
auto args1 = 0.5;
std::string arg2 = "args2";

auto msg = make_message(arg0,arg1,arg2);

unix visibility control missing

Looking at h/declspec.hpp it seems visibility control is only implemented for Windows.
I use this:

#if FLX_WIN32
  #if defined(FLX_STATIC_LINK)
    #define FLX_EXPORT
    #define FLX_IMPORT
  #else
    #define FLX_EXPORT __declspec(dllexport)
    #define FLX_IMPORT __declspec(dllimport)
  #endif
#else
  // All modules on Unix are compiled with -fvisibility=hidden
  // All API symbols get visibility default
  // whether or not we're static linking or dynamic linking (with -fPIC)
  #define FLX_EXPORT __attribute__((visibility("default"))) 
  #define FLX_IMPORT __attribute__((visibility("default"))) 
#endif

In particular note, you should compile with -fvisibility=hidden, and set the same visibility macros as shown for Unix as above. For you, these are SO_5_TYPE and SO_5_FUNC. You may need to fix your build system to ensure the default visibility is hidden.

As a comment, hidden visibility is not currently possible with static libraries. However shared libraries should always use two level namespace control. C++ Modules_TS may improve visibility control for static linkage. Its not clear if it will get rid of the need for macros like those above.

activeness if this framework

hi,
I am planning to use this framework in mqtt application .Is this project active till now and assured bugfree?

[en] On the road to SObjectizer-5.6

Motivation

Work on 5.5-branch started more than 4.5 years ago. In conditions when it was necessary to take into account compilers without a proper support of C++11, not speaking about C++14. Since then SObjectizer-5.5 is being developed with respect to old C++ compilers and with attempts to provide maximum source-code compatibility between versions inside 5.5-branch. SObjectizer-5.5 also inherited some design decisions from more earlier versions of SObjectizer-5.

As the result there are some flaws in design and implementation of SObjectizer. These flaws are the consequences of mistakes during designing SObjectizer's API and inabilities to use features from modern C++ standards. There is no way to fix those flaws without breaking compatibility between SObjectizer's versions.

It seems that there is no sense to continue development of 5.5-branch in 2019.

The goal of SObjectizer-5.6 development

The goal of SObjectizer-5.6 development is the creation of next SObjectizer version without a problems detected in 5.5-branch. The next SObjectizer version will keep the basic working principles of SObjectizer-5, but without 100% compatibility with SObjectizer-5.5.

What are planned for SObjectizer-5.6?

Remove all deprecated things

As result of 4+ years evolution of 5.5-branch a plenty of things were marked as deprecated. For example: so_5::rt namespace and send_delayed_to_agent function.

Those things are still present in SObjectizer-5.5 for the compatibility. But it is a time to cleanup SObjectizer's code base.

Every mbox will hold a reference to SObjectizer Environment

There is no way to get a reference to SObjectizer Environment from an mbox. But, in principle, it is possible for MPSC-mboxes. Alse one can get that reference from mchain and mchain can be transformed into mbox, but that mbox doesn't provides access to SObjectizer Environment.

As a result we have different versions of send_delayed and send_periodic functions in SObjectizer-5.5. In the next version of SObjectizer a reference to Environment can be obtained from any mbox. It allows to make unified versions of send_delayed and send_periodic functions, for examples: send_delayed(mbox, pause, args) and send_delayed(agent, pause, args).

Reduce count of ways to send a message

SObjectizer-5.5 has many ways to send a message. For example: several overloads of deliver_message in abstract_message_mbox_t class. It is the result of many years of SObjectizer's evolution.

It is necessary to remove some of old methods and classes intended for message sending and issuing of service requests. A couple of methods in abstract_message_t and environment_t + template functions send, send_delayed, send_periodic, request_value and request_feature should be enough.

Reduce count of event-handler's formats

Only two formats will be allowed in SObjectizer-5.6:

ret_type event_handler(mhood_t<msg_type>); // for messages and signals.
ret_type event_handler(const mhood_t<msg_type> &); // for messages and signals.

Support for ad-hoc agents will be removed

The experience shows that it is easy to declare an ordinary agent for some simple actions in modern C++. Because of that there is no sense to keep support for ad-hoc agents in SObjectizer.

Support for tuple_as_message will be removed

There is no need to support tuple_as_message after introduction of possibility to send messages of arbitrary user type (a type not inherited from so_5::message_t).

No public dispatchers any more

There were only public dispatchers in early versions of SObjectizer-5. Private dispatchers were introduced later. But now the private dispatchers are the recommended way to bind agents to some execution context.

Support for public and private dispatcher makes SObjectizer's API complex and this support is expensive in sense of SObjectizer's maintenance. Because of that only private dispatchers will be supported in SObjectizer-5.6.

Cleanup of API

Some duplicated method/functions and potentially dangerous methods/function (like those accept raw pointers) will be removed.

Where the source code of SObjectizer-5.6 will live?

Since May 2013 the source code of SObjectizer and related projects lives in Subversion-repository on SourceForge with an experimental mirror on GitHub. We plan to change that for SObjectizer-5.6.

The first reason is the speed of Svn on SF.net last year. Svn on SF.net is slow now. And sometimes the repository becomes unavailable during the problems with SF.net.

The second reason is a desire to have a simple integration with services like TravisCI (without a complex mirroring procedure).

The usage of GitHub looks like the main variant (with repository name like https://github.com/Stiffstream/sobjectizer-5-6). But some of SObjectizer's developers (eao197 as an example) don't like git and GitHub and prefer different tools.

Because of that there is an alternative: Mercurial-repo on BitBucket (with name like http://bitbucket.org/sobjectizerteam/sobjectizer-5.6). With mirror to GitHub (mirror of Hg repo much simpler than mirror of Svn-repo).

There is no the decision on this question yet.

Companion projects, like timertt and so_5_extra, will live in separate repos on the same hosting platform. Dependency management will be performed via MxxRu:::externals (like that is done now for so_5_extra).

Where the documentation for SObjectizer-5.6 will live?

This is an open question. There are three possible answers.

  1. The documentation for new version will be placed in the Wiki on SourceForge. It means that all SObjectizer's doc will be at the same place. This case simplifies writing of new doc because big fragments from old doc can be reused easily.

  2. The documentation will be placed in the Wiki of new repository. For example if BitBucket will be used for hosting of SObjectizer-5.6 code then the doc will be in Wiki on BitBucket.

  3. The documentation will be placed on stiffstream.com like it is done for RESTinio's manual.

Which C++ standard will be used for 5.6-branch?

We want to use C++17. With minimal C++ compilers like GCC 7, clang 6 and Visual C++ 15.9.3. Or even GCC 8, clang 7 and VC++ 15.9.3.

We can reduce the our requirements to C++14 standard. But only if someone tell us why this is important. If nobody asks for C++14 support we will support only C++17 and newer versions of C++.

We won't support C++11. If you really need C++11 please consider commercial support for SObjectizer.

What is the timeline?

We expect two stages of SObjectizer-5.6 development.

The first stage is the cleanup of SObjectizer's code and forming of the very first SObjectizer-5.6 version. Plus the writing of documentation and manuals for the new version. As the result of this stage the version 5.6.0 should be released. We want to ship 5.6.0 at the end of Feb 2019 (if everything will go as expected).

The next stage will begin after release of version 5.6.0. This stage is for extension of SObjectizer-5.6 functionality. It means that since v.5.6.0 new features will be added only to SObjectizer-5.6, not to SObjectizer-5.5.

How long SObjectizer-5.6 will live?

We expect that SObjectizer-5.6 will be the actual SObjectizer branch till the end of 2019. We have no plans beyond that time point.

The actual lifetime of 5.6-branch will be dictated by SObjectizer's users. The more people use SObjectizer-5.6 in their projects, the longer lifetime for SObjectizer-5.6.

What will happen with SObjectizer-5.5?

Nothing.

We will maintain SObjectizer-5.5, fix defects and publish updates until the release of SObjectizer-5.6.0. After that moment the development and maintenance of SObjectizer-5.5 will be stopped.

If you want a maintenance for SObjectizer-5.5 then you can ask for commercial support.

How can you make an influence on SObjectizer's development?

We always listen to our customers and users. So you can tell us everything you want. For example: what do you want to see in next SObjectizer's version? What do you want to remove from SObjectizer? Do you agree with usage of C++17 or maybe you need C++14? Is it OK to host SObjectizer of BitBucket or maybe you can work with GitHub only?

Your answers to those questions make our further development of SObjectiver much easier.

[ru] Приоритеты для сообщений в версии 5.5.5

В чем смысл данного обсуждения?

Данная тема преследует две цели:

  1. Собрать мнения и/или информацию о том, нужны ли приоритеты, есть ли ситуации, где без приоритетов либо не обойтись вообще, либо же это будет обходиться очень дорого. Или же выяснить, что в озвученных ситуациях есть хорошие решения и без приоритетов.
  2. Если в процессе обсуждения выяснится, что в SO-5 желательно иметь поддержку приоритетов, то определить, каким образом это могло бы выглядеть (хотя бы в первом приближении).

Нужны ли приоритеты?

Приоритеты событий поддерживались в SObjectizer-4. Но за все время активного использования SO-4 приоритеты были задействованы всего лишь считанные разы. При этом за поддержку приоритетов приходилось платить более сложной реализацией очередей заявок и невозможностью проведения некоторых оптимизаций при обслуживании очередей.

Поэтому SObjectizer-5 сразу создавали без поддержки приоритетов. Это серьезно упростило реализацию SO-5, а так же позволило существенно повысить скорость сохранения/извлечения заявок при диспетчеризации сообщений. Так же за время практического использования SO-5 (т.е. где-то с 2011-го года) не было ситуаций, где необходимость поддержки приоритетов была бы критически важна.

Однако, по мере развития, совершенствования и наполнения SO-5 новыми, полезными для разработчика возможностями, возникает вопрос: “Не пора ли вернуться к теме приоритетов?”

Примеры ситуаций для приоритетов

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

Контроль перегрузки агента

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

Т.к. только агент может сменить свое состояние, то для воплощения такой схемы контроля за перегрузкой нужно отослать сообщение агенту и дать возможность агенту обработать это сообщение раньше всех остальных сообщений, которые уже стоят у него в очереди. А это ни что иное, как приоритетная обработка сообщений. Но т.к. в SO-5 поддержки приоритетов нет, то такую схему в существующем SObjectizer реализовать не представляется возможным.

Распределение работы между вокерами

Простая ситуация: есть агент-менеджер, который получает сообщения-заявки и несколько подчиненных ему агентов-воркеров. Менеджер ведет список свободных воркеров. Когда менеджер получает очередную заявку, он изымает из списка свободного воркера и отдает заявку этому воркеру. Если свободных воркеров нет, то менеджер сразу отказывается от обработки заявки и отсылает отрицательный ответ.

Агенты-воркеры информируют менеджера о том, что они освободились, простыми сообщениями. Когда менеджер получает сообщение о том, что воркер свободен, он сохраняет воркера в список свободных воркеров.

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

(task(i),task(i+1),task(i+2),free_worker(j),free_worker(k))

Т.е. три новые заявки, за которыми идут два сообщения об освободившихся воркерах.

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

Если бы у сообщений free_worker были бы более высокие приоритеты, то очередь заявок к менеджеру имела бы вид:

(free_worker(j),free_worker(k),task(i),task(i+1),task(i+2))

Ее последовательная обработка привела бы к тому, что сначала в список свободных воркеров была бы сохранена информация о двух свободных агентах. После чего им были бы переданы две заявки. А отброшена была бы только третья.

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

Если приоритеты нужны, то какие?

per-agent-prio и per-queue-prio

На самом деле в SO-5 нет такой штуки, как очередь заявок агента. Есть очередь заявок для рабочей нити (в thread_pool/adv_thread_pool-диспетчерах чуть сложнее, но сути это не меняет).

Если агент работает на рабочей нити один, то очередь заявок нити оказывается очередью заявок агента. Но если агент работает на рабочей нити не один, то заявки всех агентов в этой очереди “перемешиваются”. Что приводит к вопросу: если в очереди заявок размещаются заявки для разных агентов, то как следует поступать с приоритетными заявками, которые попадают в эту очередь?

Представляется, что есть два подхода:

  • механизм per-agent-prio означает, что приоритеты событий имеют значение только для одного агента. Допустим, что есть агенты A, B и C, разделяющие общую очередь заявок. Эта очередь на данный момент имеет вид (m1(A),m2(B),m3(C),m4(B)). Т.е. сначала сообщение для A, затем для B, затем для C и последнее опять для B. Приходит очередное сообщение m5 для B, приоритет которого выше, чем приоритет сообщений m2 и m4. Очередь заявок должна принять вид (m1(A),m5(B),m3(C),m2(B),m4(B)). Т.е. приоритетное сообщение меняет порядок сообщений только для B;
  • механизм per-queue-prio означает, что приоритеты событий сказываются на всей очереди. Т.е. если в примере (m1(A),m2(B),m3(C),m4(B)) сообщение m5 для B имеет самый высокий приоритет среди всех сообщений m1..m4, то очередь заявок должна принять вид (m5(B),m1(A),m2(B),m3(C),m4(B)).

Однако, если попробовать спроецировать эти подходы на то, что встречается на практике, то получается, что для механизма per-agent-prio примеры использования придумать можно. Так, два описанных выше сценария использования приоритетов (контроль перегрузки и распределение работы между воркерами), требуют механизма per-agent-prio.

Поэтому, если у кого-то есть примеры сценариев использования per-queue-prio, то просьба оставить их в комментариях.

[en] how to integrate extenral loop in SO?

I'm not sure that I do the right integration of a loop. Basically I do:

void my_actor::so_evt_start() {
    so_subscribe_self().event<message::wakeup>(&wx_actor::on_wakeup);
    timer = so_5::send_periodic<message::wakeup>(*this, 0ms, 10ms);
}

void my_actor:::on_wakeup() {
    auto has_events = external_loop->Pending();
    while(has_events) {
        external_loop->DispatchTimeout(10); // can be just non-blocking external_loop->DispatchTimeout(()
        has_events = external_loop->Pending();
    }
    timer = so_5::send_periodic<message::wakeup>(*this, 10ms, 0ms);
}

in other words, it blocks SO-dispatcher for 10ms to process events, and then does 10ms pause, and repeats.

I'm a bit worry, that on idle it still consumes a lot of CPU (14%). If the wake-up event is send every 100ms there is no CPU consumption, but by the price of loosing some interactivity.

May be there are some other ways? i.e. not guessing the values between 100ms and 10ms ?

PS. The external loop I'm trying to integrate is wx-widget ( https://docs.wxwidgets.org/3.0/classwx_event_loop_base.html )

PPS. I'm aware, that it is possible to do that in "wx-widgets" specific way, i.e. launch an dedicated thread, and deliver events in framework-specific way ( i.e. https://wiki.wxwidgets.org/Inter-Thread_and_Inter-Process_communication ). But I'd like to use nice sobjectizer as messaging framework.

so Hello World fails to compile with no member named 'in_place' in namespace 'std' error

I pulled SO and built it with cmake. I use the following cmake file for my project

cmake_minimum_required(VERSION 3.13)
project(Experimen-1)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)


add_executable(experiment_1
  main.cpp
)

set(DEP_DIR "/home/my_name/il_dependencies/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")

SET (sobjectizer_DIR "${DEP_DIR}lib/cmake/sobjectizer" )
find_package( sobjectizer REQUIRED )

target_include_directories( experiment_1 BEFORE PRIVATE "${DEP_DIR}/include" )
target_link_libraries( experiment_1 PRIVATE  sobjectizer::SharedLib )

The code in main is very simple, not even launching environment

#include <iostream>
#include <so_5/all.hpp>

int main() {
  std::cout << "Works...\n" ;
}

When I try to build I get long list of errors. First error message being:

In file included from /home/boris/projects/thesis/so5_experiments/experiment-1/m
ain.cpp:3:
In file included from /home/boris/il_dependencies/include/so_5/all.hpp:15:
In file included from /home/boris/il_dependencies/include/so_5/rt/h/rt.hpp:13:
In file included from /home/boris/il_dependencies/include/so_5/rt/h/agent.hpp:30
:
In file included from /home/boris/il_dependencies/include/so_5/rt/h/agent_contex
t.hpp:17:
In file included from /home/boris/il_dependencies/include/so_5/rt/h/agent_tuning
_options.hpp:16:
In file included from /home/boris/il_dependencies/include/so_5/rt/h/message_limi
t.hpp:16:
In file included from /home/boris/il_dependencies/include/so_5/rt/h/enveloped_ms
g.hpp:17:
In file included from /home/boris/il_dependencies/include/so_5/h/optional.hpp:15
:
/home/boris/il_dependencies/include/so_5/3rd_party/optional-lite/nonstd/optional
.hpp:319:12: error:
      no member named 'in_place' in namespace 'std'
using std::in_place;
      ~~~~~^

I use clang 6 to compile and it support C++17. So it should support std::in_place but code also fails:

#include <iostream>
#include <utility>
using std::in_place;

int main() {
  std::cout << "Works...\n" ;
}

Might be that there is something wrong with my environment

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.