universal primitive of concurrent computation More...
#include <actor_base.h>
Public Types | |
using | config_t = actor_config_t |
injects an alias for actor_config_t | |
template<typename Actor > | |
using | config_builder_t = actor_config_builder_t< Actor > |
injects templated actor_config_builder_t | |
template<typename Handler > | |
using | is_handler = std::enable_if_t< std::is_member_function_pointer_v< Handler >||std::is_base_of_v< handler_base_t, Handler > > |
SFINAE handler detector. | |
using | plugins_list_t = std::tuple< plugin::address_maker_plugin_t, plugin::lifetime_plugin_t, plugin::init_shutdown_plugin_t, plugin::link_server_plugin_t, plugin::link_client_plugin_t, plugin::registry_plugin_t, plugin::resources_plugin_t, plugin::starter_plugin_t > |
the default list of plugins for an actor | |
Public Member Functions | |
actor_base_t (config_t &cfg) | |
constructs actor and links it's supervisor | |
virtual void | do_initialize (system_context_t *ctx) noexcept |
early actor initialization (pre-initialization) | |
virtual void | do_shutdown (const extended_error_ptr_t &reason={}) noexcept |
convenient method to send actor's supervisor shutdown trigger message | |
virtual void | on_start () noexcept |
actor is fully initialized and it's supervisor has sent signal to start | |
template<typename M , typename... Args> | |
void | send (const address_ptr_t &addr, Args &&...args) |
sends message to the destination address | |
template<typename R , typename... Args> | |
request_builder_t< typename request_wrapper_t< R >::request_t > | request (const address_ptr_t &dest_addr, Args &&...args) |
returns request builder for destination address using the "main" actor address | |
template<typename R , typename... Args> | |
request_builder_t< typename request_wrapper_t< R >::request_t > | request_via (const address_ptr_t &dest_addr, const address_ptr_t &reply_addr, Args &&...args) |
returns request builder for destination address using the specified address for reply | |
template<typename Request , typename... Args> | |
void | reply_to (Request &message, Args &&...args) |
convenient method for constructing and sending response to a request | |
template<typename Request > | |
void | reply_with_error (Request &message, const extended_error_ptr_t &ec) |
convenient method for constructing and sending error response to a request | |
template<typename Request , typename... Args> | |
auto | make_response (Request &message, Args &&...args) |
makes response to the request, but does not send it. | |
template<typename Request > | |
auto | make_response (Request &message, const extended_error_ptr_t &ec) |
makes error response to the request, but does not send it. | |
template<typename Handler > | |
subscription_info_ptr_t | subscribe (Handler &&h, const address_ptr_t &addr) noexcept |
subscribes actor's handler to process messages on the specified address | |
template<typename Handler > | |
subscription_info_ptr_t | subscribe (Handler &&h) noexcept |
subscribes actor's handler to process messages on the actor's "main" address | |
template<typename Handler , typename = is_handler<Handler>> | |
void | unsubscribe (Handler &&h, address_ptr_t &addr) noexcept |
unsubscribes actor's handler from process messages on the specified address | |
template<typename Handler , typename = is_handler<Handler>> | |
void | unsubscribe (Handler &&h) noexcept |
unsubscribes actor's handler from processing messages on the actor's "main" address | |
void | unsubscribe (const handler_ptr_t &h) noexcept |
initiates handler unsubscription from the default actor address | |
void | activate_plugins () noexcept |
starts plugins activation | |
void | commit_plugin_activation (plugin::plugin_base_t &plugin, bool success) noexcept |
finishes plugin activation, successful or not | |
void | deactivate_plugins () noexcept |
starts plugins deactivation | |
void | commit_plugin_deactivation (plugin::plugin_base_t &plugin) noexcept |
finishes plugin deactivation | |
void | on_subscription (message::subscription_t &message) noexcept |
propagates subscription message to corresponding actors | |
void | on_unsubscription (message::unsubscription_t &message) noexcept |
propagates unsubscription message to corresponding actors | |
void | on_unsubscription_external (message::unsubscription_external_t &message) noexcept |
propagates external unsubscription message to corresponding actors | |
address_ptr_t | create_address () noexcept |
creates new unique address for an actor (via address_maker plugin) | |
virtual void | shutdown_start () noexcept |
starts shutdown procedure, e.g. upon receiving shutdown request | |
void | shutdown_continue () noexcept |
polls plugins for shutdown | |
virtual void | shutdown_finish () noexcept |
finalizes shutdown | |
virtual void | init_start () noexcept |
starts initialization procedure | |
void | init_continue () noexcept |
polls plugins whether they completed initialization. | |
virtual void | init_finish () noexcept |
finalizes initialization | |
virtual void | configure (plugin::plugin_base_t &plugin) noexcept |
main callback for plugin configuration when it's ready | |
template<typename T > | |
auto & | access () noexcept |
generic non-public fields accessor | |
template<typename T , typename... Args> | |
auto | access (Args... args) noexcept |
generic non-public methods accessor | |
template<typename T > | |
auto & | access () const noexcept |
generic non-public fields accessor | |
template<typename T , typename... Args> | |
auto | access (Args... args) const noexcept |
generic non-public methods accessor | |
const address_ptr_t & | get_address () const noexcept |
returns actor's main address | |
supervisor_t & | get_supervisor () const noexcept |
returns actor's supervisor | |
template<typename Delegate , typename Method , typename = std::enable_if_t<std::is_invocable_v<Method, Delegate *, request_id_t, bool>>> | |
request_id_t | start_timer (const pt::time_duration &interval, Delegate &delegate, Method method) noexcept |
spawns a new one-shot timer | |
void | cancel_timer (request_id_t request_id) noexcept |
cancels previously started timer | |
const extended_error_ptr_t & | get_shutdown_reason () const noexcept |
returns actor shutdown reason | |
const std::string & | get_identity () const noexcept |
retuns human-readable actor identity | |
virtual bool | should_restart () const noexcept |
whether spawner should create a new instance of the actor | |
template<typename Request , typename... Args> | |
request_builder_t< typename request_wrapper_t< Request >::request_t > | request (const address_ptr_t &dest_addr, Args &&...args) |
makes an request to the destination address with the message constructed from args | |
template<typename Request , typename... Args> | |
request_builder_t< typename request_wrapper_t< Request >::request_t > | request_via (const address_ptr_t &dest_addr, const address_ptr_t &reply_addr, Args &&...args) |
makes an request to the destination address with the message constructed from args | |
Static Public Attributes | |
static const constexpr std::uint32_t | PROGRESS_INIT = 1 << 0 |
flag to mark, that actor is already executing initialization | |
static const constexpr std::uint32_t | PROGRESS_SHUTDOWN = 1 << 1 |
flag to mark, that actor is already executing shutdown | |
static const constexpr std::uint32_t | ESCALATE_FALIURE = 1 << 2 |
flag to mark, that actor is already executing shutdown | |
static const constexpr std::uint32_t | AUTOSHUTDOWN_SUPERVISOR = 1 << 3 |
flag to mark, that actor trigger supervisor shutdown | |
Protected Types | |
using | timers_map_t = std::unordered_map< request_id_t, timer_handler_ptr_t > |
timer-id to timer-handler map (type) | |
using | requests_t = std::unordered_set< request_id_t > |
list of ids of active requests (type) | |
Protected Member Functions | |
void | on_timer_trigger (request_id_t request_id, bool cancelled) noexcept |
triggers timer handler associated with the timer id | |
template<typename Delegate , typename Method > | |
void | start_timer (request_id_t request_id, const pt::time_duration &interval, Delegate &delegate, Method method) noexcept |
starts timer with pre-forged timer id (aka request-id | |
void | assign_shutdown_reason (extended_error_ptr_t reason) noexcept |
helper-method, which assigns shutdown reason if it isn't set | |
extended_error_ptr_t | make_error (const std::error_code &ec, const extended_error_ptr_t &next={}, const message_ptr_t &request={}) const noexcept |
makes extended error within the context of the actor | |
virtual bool | on_unlink (const address_ptr_t &server_addr) noexcept |
notification, when actor has been unlinked from server actor | |
plugin::plugin_base_t * | get_plugin (const std::type_index &) const noexcept |
finds plugin by plugin class identity | |
Protected Attributes | |
intrusive_ptr_t< message::init_request_t > | init_request |
suspended init request message | |
intrusive_ptr_t< message::shutdown_request_t > | shutdown_request |
suspended shutdown request message | |
address_ptr_t | address |
actor address | |
address_ptr_t | spawner_address |
actor spawner address | |
std::string | identity |
actor identity, which might have some meaning for developers | |
supervisor_t * | supervisor |
non-owning pointer to actor's execution / infrastructure context | |
plugin_storage_ptr_t | plugins_storage |
opaque plugins storage (owning) | |
plugins_t | plugins |
non-owning list of plugins | |
pt::time_duration | init_timeout |
timeout for actor initialization (used by supervisor) | |
pt::time_duration | shutdown_timeout |
timeout for actor shutdown (used by supervisor) | |
state_t | state |
current actor state | |
plugin::address_maker_plugin_t * | address_maker = nullptr |
non-owning pointer to address_maker plugin | |
plugin::lifetime_plugin_t * | lifetime = nullptr |
non-owning pointer to lifetime plugin | |
plugin::link_server_plugin_t * | link_server = nullptr |
non-owning pointer to link_server plugin | |
plugin::resources_plugin_t * | resources = nullptr |
non-owning pointer to resources plugin | |
std::set< const std::type_index * > | activating_plugins |
set of activating plugin identities | |
std::set< const std::type_index * > | deactivating_plugins |
set of deactivating plugin identities | |
timers_map_t | timers_map |
timer-id to timer-handler map | |
requests_t | active_requests |
list of ids of active requests | |
std::uint32_t | continuation_mask = 0 |
set of currently processing states, i.e. init or shutdown | |
extended_error_ptr_t | shutdown_reason |
explanation, why actor is been requested for shut down | |
Friends | |
struct | plugin::plugin_base_t |
struct | plugin::lifetime_plugin_t |
struct | supervisor_t |
template<typename T > | |
struct | request_builder_t |
template<typename T , typename M > | |
struct | accessor_t |
universal primitive of concurrent computation
The class is base class for user-defined actors. It is expected that actors will react on incoming messages (e.g. by changing internal /private state) or send (other) messages to other actors, or do some side-effects (I/O, etc.).
Message passing interface is asynchronous, they are send to supervisor_t
.
Every actor belong to some supervisor_t
, which "injects" the thread-safe execution context, in a sense, that the actor can call it's own methods as well as supervisors without any need of synchronization.
All actor methods are thread-unsafe, i.e. should not be called with except of it's own supervisor. Communication with actor should be performed via messages.
Actor is addressed by it's "main" address; however it is possible for an actor to have multiple identities aka "virtual" addresses.
using rotor::actor_base_t::is_handler = std::enable_if_t<std::is_member_function_pointer_v<Handler> || std::is_base_of_v<handler_base_t, Handler> > |
SFINAE handler detector.
Either handler can be constructed from member-to-function-pointer or it is already constructed and have a base handler_base_t
the default list of plugins for an actor
The order of plugins is very important, as they are initialized in the direct order and deinitialized in the reverse order.
rotor::actor_base_t::actor_base_t | ( | config_t & | cfg | ) |
constructs actor and links it's supervisor
An actor cannot outlive it's supervisor.
Sets internal actor state to NEW
|
noexcept |
cancels previously started timer
If timer hasn't been triggered, then it is cancelled and the callback will be invoked with true
to mark that it was cancelled.
Upon cancellation the timer callback will be invoked immediately, in the context of caller.
|
virtualnoexcept |
main callback for plugin configuration when it's ready
Reimplemented in rotor::registry_t.
|
virtualnoexcept |
early actor initialization (pre-initialization)
Actor's plugins are activated, "main" address is created (via plugin::address_maker_plugin_t
), state is set to INITIALIZING
(via plugin::init_shutdown_plugin_t
).
Reimplemented in rotor::ev::supervisor_ev_t, and rotor::supervisor_t.
|
virtualnoexcept |
convenient method to send actor's supervisor shutdown trigger message
If actor is already shutting down, the method will do nothing, otherwise it will send shutdown trigger to its supervisor.
The shutdown reason is forwarded "as is". If it is missing, than it will be constructed with the error code "normal shutdown".
Reimplemented in rotor::supervisor_t.
|
inlinenoexcept |
retuns human-readable actor identity
The identity can be assigned either directly in ctor, or via address_maker plugin
|
protectednoexcept |
finds plugin by plugin class identity
nullptr
is returned when plugin cannot be found
|
inlinenoexcept |
returns actor shutdown reason
The shutdown reason should be available if actors' state is already SHUTTING_DOWN
|
noexcept |
polls plugins whether they completed initialization.
The poll is performed in the direct order. If all plugins, with active init reaction confirm they are ready, then the init_finish
method is invoked.
|
virtualnoexcept |
finalizes initialization
The init response is sent and actor state is set to INITIALIZED.
|
virtualnoexcept |
starts initialization procedure
The actor state is set to INITIALIZING.
auto rotor::actor_base_t::make_response | ( | Request & | message, |
Args &&... | args | ||
) |
makes response to the request, but does not send it.
The return type is intrusive pointer to the message, not the message itself.
It can be useful for delayed responses. The response can be dispatched later via supervisor->put(std::move(response_ptr));
auto rotor::actor_base_t::make_response | ( | Request & | message, |
const extended_error_ptr_t & | ec | ||
) |
makes error response to the request, but does not send it.
The return type is intrusive pointer to the message, not the message itself.
It can be useful for delayed responses. The response can be dispatched later via supervisor->put(std::move(response_ptr));
|
virtualnoexcept |
actor is fully initialized and it's supervisor has sent signal to start
The actor state is set to OPERATIONAL
.
Reimplemented in rotor::supervisor_t.
|
protectedvirtualnoexcept |
notification, when actor has been unlinked from server actor
Returns boolean, meaning whether actor should initiate shutdown. Default value is true
.
void rotor::actor_base_t::reply_to | ( | Request & | message, |
Args &&... | args | ||
) |
convenient method for constructing and sending response to a request
args
are forwarded to response payload construction
request_builder_t< typename request_wrapper_t< R >::request_t > rotor::actor_base_t::request | ( | const address_ptr_t & | dest_addr, |
Args &&... | args | ||
) |
returns request builder for destination address using the "main" actor address
The args
are forwarded for construction of the request. The request is not actually sent, until send
method of request_builder_t
will be invoked.
Supervisor will spawn timeout timer upon timeout
method.
request_builder_t< typename request_wrapper_t< Request >::request_t > rotor::actor_base_t::request | ( | const address_ptr_t & | dest_addr, |
Args &&... | args | ||
) |
makes an request to the destination address with the message constructed from args
The reply_to
address is defaulted to actor's main address.1
request_builder_t< typename request_wrapper_t< R >::request_t > rotor::actor_base_t::request_via | ( | const address_ptr_t & | dest_addr, |
const address_ptr_t & | reply_addr, | ||
Args &&... | args | ||
) |
returns request builder for destination address using the specified address for reply
It is assumed, that the specified address belongs to the actor.
The method is useful, when a different behavior is needed for the same message response types. It serves at some extend as virtual dispatching within the actor.
See the description of request
method.
request_builder_t< typename request_wrapper_t< Request >::request_t > rotor::actor_base_t::request_via | ( | const address_ptr_t & | dest_addr, |
const address_ptr_t & | reply_addr, | ||
Args &&... | args | ||
) |
makes an request to the destination address with the message constructed from args
The reply_addr
is used to specify the exact destination address, where reply should be delivered.
void rotor::actor_base_t::send | ( | const address_ptr_t & | addr, |
Args &&... | args | ||
) |
sends message to the destination address
The provided arguments are used for the construction of payload, which is, in turn, is wrapped into message.
Internally the new message is placed into supervisor's outbound queue.
|
virtualnoexcept |
whether spawner should create a new instance of the actor
When then actor is spawned via a spawner, and it becomes down, the spawner will ask the current instance whether it should spawn another one.
This method is consulted, only when spawner's restart_policy_t is ask_actor
.
|
noexcept |
polls plugins for shutdown
The poll is performed in the reverse order. If all plugins, with active shutdown reaction confirm they are ready to shutdown, then the shutdown_finish
method is invoked.
|
virtualnoexcept |
finalizes shutdown
The shutdown response is sent and actor state is set to SHUT_DOWN.
This is the last action in the shutdown sequence. No further methods will be invoked on the actor.
All unfinished requests and untriggered timers will be cancelled by force in the method.
Reimplemented in rotor::asio::supervisor_asio_t, rotor::ev::supervisor_ev_t, and rotor::supervisor_t.
|
virtualnoexcept |
starts shutdown procedure, e.g. upon receiving shutdown request
The actor state is set to SHUTTING_DOWN.
|
noexcept |
spawns a new one-shot timer
interval | specifies amount of time, after which the timer will trigger. |
delegate | is an object of arbitrary class. |
method | is the pointer-to-member-function of the object or callback, which will be invoked upon timer triggering or cancellation. |
The method
parameter should have the following signatures:
void Delegate::on_timer(request_id_t, bool cancelled) noexcept;
or
void(Delegate*,request_id_t, bool cancelled) noexcept
start_timer
returns timer identity. It will be supplied to the specified callback, or the timer can be cancelled via it.
|
staticconstexpr |
flag to mark, that actor trigger supervisor shutdown
When actor is shutdown (for whatever reason), if this flag is ON, then it will trigger it's supervisor shutdown.
This policy is ignored when actor is spawned.
|
protected |
set of currently processing states, i.e. init or shutdown
This is not the same as state_t
flag, which just marks the state.
The continuation_mask
is mostly used by plugins to avoid recursion
|
staticconstexpr |
flag to mark, that actor is already executing shutdown
When actor is shutdown due to failure, if this flag is ON, then it will trigger it's supervisor shutdown.
This policy is ignored when actor is spawned.