Stiffstream / sobjectizer

An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.

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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[idea] A possibility to set a custom mbox to be returned via agent_t::so_direct_mbox()?

eao197 opened this issue · comments

This is just an idea. It's fixed here to be investigated and, maybe, implemented in some future version of SObjectizer.

Every agent in SObjectizer has its MPSC mbox called direct mbox. This mbox is automatically created by SOEnv for every new agent. That mbox is available via agent_t::so_direct_mbox() method.

The type of that mbox is hidden from a user. A user only knows that it's an MPSC mbox.

Sometimes it can be necessary to hide the agent direct mbox and to expose some proxy instead (for example, a proxy that filters or reorders messages of some types), but it's impossible to do because anyone who has a reference to an agent can call so_direct_mbox, and so_direct_mbox isn't a virtual method.

I think that SObjectizer should have a way to specify a custom MPSC mbox to be used as the agent's direct mbox. But I don't know how to do that at the moment. It requires further thinking and prototyping.

A possible way to do that can look like this:

namespace so_5 {

// Type for a factory for custom direct mboxes.
using direct_mbox_factory_t = std::function<
  mbox_t(agent_context_t & ctx, so_5::mbox_t actual_mbox) >;

class agent_tuning_options_t
{
public:
  ...
  agent_tuning_options_t &
  custom_direct_mbox_factory(direct_mbox_factory_t factory) {...}
  ...
};
...
class agent_t
{
  ...
protected:
  ...
  template<typename Lambda>
  [[nodiscard]]
  static direct_mbox_factory_t
  direct_mbox_factory(Lambda && lambda) { return { std::forward<Lambda>(lambda) }; }
  ...
};

} /* namespace so_5 */

It allows to write code like that:

class my_agent_with_custom_mbox : public so_5::agent_t
{
public:
  my_agent_with_custom_mbox(context_t ctx, ...)
    : so_5::agent_t{ ctx
        + direct_mbox_factory( [](so_5::agent_context_t & ctx, so_5::mbox_t actual_mbox) {
          return make_some_proxy(ctx.environment(), std::move(actual_mbox));
        })
      }
  {}
};

The mbox returned by the custom factory will be stored inside the agent as its direct mbox. That value then will be returned by so_direct_mbox() method (the so_direct_mbox will still be non-virtual method).

Is available now in v.5.7.4.