rotor
Event loop friendly C++ actor micro-framework
Loading...
Searching...
No Matches
actor_base.h
1#pragma once
2
3//
4// Copyright (c) 2019-2025 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
5//
6// Distributed under the MIT Software License
7//
8
9#include "forward.hpp"
10#include "address.hpp"
11#include "actor_config.h"
12#include "messages.hpp"
13#include "state.h"
14#include "handler.h"
15#include "extended_error.h"
16#include "timer_handler.hpp"
17#include <set>
18
19#if defined(_MSC_VER)
20#pragma warning(push)
21#pragma warning(disable : 4251)
22#endif
23
24namespace rotor {
25
47struct ROTOR_API actor_base_t : public arc_base_t<actor_base_t> {
50
52 template <typename Actor> using config_builder_t = actor_config_builder_t<Actor>;
53
59 template <typename Handler>
60 using is_handler =
61 std::enable_if_t<std::is_member_function_pointer_v<Handler> || std::is_base_of_v<handler_base_t, Handler>>;
62
63 // clang-format off
70 using plugins_list_t = std::tuple<
79 // clang-format on
80
89 virtual ~actor_base_t();
90
98 virtual void do_initialize(system_context_t *ctx) noexcept;
99
108 virtual void do_shutdown(const extended_error_ptr_t &reason = {}) noexcept;
109
115 virtual void on_start() noexcept;
116
125 template <typename M, typename... Args> void send(const address_ptr_t &addr, Args &&...args);
126
142 template <typename M, typename... Args>
143 void route(const address_ptr_t &addr, const address_ptr_t &next_addr, Args &&...args);
144
148 void redirect(message_ptr_t message, const address_ptr_t &addr, const address_ptr_t &next_addr = {}) noexcept;
149
157 template <typename R, typename... Args>
158 request_builder_t<typename request_wrapper_t<R>::request_t> request(const address_ptr_t &dest_addr, Args &&...args);
159
171 template <typename R, typename... Args>
172 request_builder_t<typename request_wrapper_t<R>::request_t>
173 request_via(const address_ptr_t &dest_addr, const address_ptr_t &reply_addr, Args &&...args);
174
179 template <typename Request, typename... Args> void reply_to(Request &message, Args &&...args);
180
182 template <typename Request> void reply_with_error(Request &message, const extended_error_ptr_t &ec);
183
192 template <typename Request, typename... Args> auto make_response(Request &message, Args &&...args);
193
202 template <typename Request> auto make_response(Request &message, const extended_error_ptr_t &ec);
203
205 template <typename Handler> subscription_info_ptr_t subscribe(Handler &&h, const address_ptr_t &addr) noexcept;
206
208 template <typename Handler> subscription_info_ptr_t subscribe(Handler &&h) noexcept;
209
211 template <typename Handler, typename = is_handler<Handler>>
212 void unsubscribe(Handler &&h, address_ptr_t &addr) noexcept;
213
215 template <typename Handler, typename = is_handler<Handler>> void unsubscribe(Handler &&h) noexcept;
216
217 /* \brief initiates handler unsubscription from the address
218 *
219 * If the address is local, then unsubscription confirmation is sent immediately,
220 * otherwise {@link payload::external_subscription_t} request is sent to the external
221 * supervisor, which owns the address.
222 *
223 * The optional call can be provided to be called upon message destruction.
224 *
225 */
226
228 inline void unsubscribe(const handler_ptr_t &h) noexcept { lifetime->unsubscribe(h, address); }
229
231 void activate_plugins() noexcept;
232
234 void commit_plugin_activation(plugin::plugin_base_t &plugin, bool success) noexcept;
235
237 void deactivate_plugins() noexcept;
238
240 void commit_plugin_deactivation(plugin::plugin_base_t &plugin) noexcept;
241
244
246 void on_unsubscription(message::unsubscription_t &message) noexcept;
247
249 void on_unsubscription_external(message::unsubscription_external_t &message) noexcept;
250
253
259 virtual void shutdown_start() noexcept;
260
268 void shutdown_continue() noexcept;
269
281 virtual void shutdown_finish() noexcept;
282
288 virtual void init_start() noexcept;
289
297 void init_continue() noexcept;
298
304 virtual void init_finish() noexcept;
305
307 virtual void configure(plugin::plugin_base_t &plugin) noexcept;
308
310 template <typename T> auto &access() noexcept;
311
313 template <typename T, typename... Args> auto access(Args... args) noexcept;
314
316 template <typename T> auto &access() const noexcept;
317
319 template <typename T, typename... Args> auto access(Args... args) const noexcept;
320
322 inline const address_ptr_t &get_address() const noexcept { return address; }
323
325 inline supervisor_t &get_supervisor() const noexcept { return *supervisor; }
326
345 template <typename Delegate, typename Method,
346 typename = std::enable_if_t<std::is_invocable_v<Method, Delegate *, request_id_t, bool>>>
347 request_id_t start_timer(const pt::time_duration &interval, Delegate &delegate, Method method) noexcept;
348
356 void cancel_timer(request_id_t request_id) noexcept;
357
363 inline const extended_error_ptr_t &get_shutdown_reason() const noexcept { return shutdown_reason; }
364
370 inline const std::string &get_identity() const noexcept { return identity; }
371
373 static const constexpr std::uint32_t PROGRESS_INIT = 1 << 0;
374
376 static const constexpr std::uint32_t PROGRESS_SHUTDOWN = 1 << 1;
377
386 static const constexpr std::uint32_t ESCALATE_FALIURE = 1 << 2;
387
396 static const constexpr std::uint32_t AUTOSHUTDOWN_SUPERVISOR = 1 << 3;
397
408 virtual bool should_restart() const noexcept;
409
410 protected:
412 using timers_map_t = std::unordered_map<request_id_t, timer_handler_ptr_t>;
413
415 using requests_t = std::unordered_set<request_id_t>;
416
418 void on_timer_trigger(request_id_t request_id, bool cancelled) noexcept;
419
421 template <typename Delegate, typename Method>
422 void start_timer(request_id_t request_id, const pt::time_duration &interval, Delegate &delegate,
423 Method method) noexcept;
424
427
429 extended_error_ptr_t make_error(const std::error_code &ec, const extended_error_ptr_t &next = {},
430 const message_ptr_t &request = {}) const noexcept;
431
437 virtual bool on_unlink(const address_ptr_t &server_addr) noexcept;
438
441
444
447
450
452 std::string identity;
453
455 supervisor_t *supervisor;
456
459
462
464 pt::time_duration init_timeout;
465
467 pt::time_duration shutdown_timeout;
468
471
474
477
480
483
488 plugin::plugin_base_t *get_plugin(const std::type_index &) const noexcept;
489
491 std::set<const std::type_index *> activating_plugins;
492
494 std::set<const std::type_index *> deactivating_plugins;
495
498
501
509 std::uint32_t continuation_mask = 0;
510
513
514 friend struct plugin::plugin_base_t;
515 friend struct plugin::lifetime_plugin_t;
516 friend struct supervisor_t;
517 template <typename T> friend struct request_builder_t;
518 template <typename T, typename M> friend struct accessor_t;
519};
520
521} // namespace rotor
522
523#if defined(_MSC_VER)
524#pragma warning(pop)
525#endif
namespace for rotor core messages (which just transform payloads)
Definition messages.hpp:317
Basic namespace for all rotor functionalities.
Definition rotor.hpp:21
std::deque< plugin::plugin_base_t * > plugins_t
list of raw plugin pointers
Definition actor_config.h:26
intrusive_ptr_t< extended_error_t > extended_error_ptr_t
intrusive pointer to extended error type
Definition extended_error.h:25
intrusive_ptr_t< message_base_t > message_ptr_t
intrusive pointer for message
Definition message.h:118
std::unique_ptr< timer_handler_base_t > timer_handler_ptr_t
alias for timer smart pointer
Definition timer_handler.hpp:36
std::unique_ptr< plugin_storage_base_t > plugin_storage_ptr_t
smart pointer for plugin_storage_base_t
Definition actor_config.h:38
intrusive_ptr_t< handler_base_t > handler_ptr_t
intrusive pointer for handler
Definition forward.hpp:26
state_t
state of actor in rotor
Definition state.h:12
intrusive_ptr_t< address_t > address_ptr_t
intrusive pointer for address
Definition address.hpp:57
boost::intrusive_ref_counter< T, counter_policy_t > arc_base_t
base class to inject ref-counter with the specified policy
Definition arc.hpp:24
boost::intrusive_ptr< T > intrusive_ptr_t
alias for intrusive pointer
Definition arc.hpp:27
std::size_t request_id_t
timer identifier type in the scope of the actor
Definition forward.hpp:34
intrusive_ptr_t< subscription_info_t > subscription_info_ptr_t
intrusive pointer for subscription_info_t
Definition subscription_point.h:121
void on_unsubscription_external(message::unsubscription_external_t &message) noexcept
propagates external unsubscription message to corresponding actors
static const constexpr std::uint32_t ESCALATE_FALIURE
flag to mark, that actor is already executing shutdown
Definition actor_base.h:386
void redirect(message_ptr_t message, const address_ptr_t &addr, const address_ptr_t &next_addr={}) noexcept
redirects premade message into destination address (and them, possibly routes it to `next_address)
virtual void configure(plugin::plugin_base_t &plugin) noexcept
main callback for plugin configuration when it's ready
void deactivate_plugins() noexcept
starts plugins deactivation
plugin::link_server_plugin_t * link_server
non-owning pointer to link_server plugin
Definition actor_base.h:479
actor_config_builder_t< Actor > config_builder_t
injects templated actor_config_builder_t
Definition actor_base.h:52
void commit_plugin_activation(plugin::plugin_base_t &plugin, bool success) noexcept
finishes plugin activation, successful or not
void shutdown_continue() noexcept
polls plugins for shutdown
void on_timer_trigger(request_id_t request_id, bool cancelled) noexcept
triggers timer handler associated with the timer id
static const constexpr std::uint32_t PROGRESS_INIT
flag to mark, that actor is already executing initialization
Definition actor_base.h:373
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
request_id_t start_timer(const pt::time_duration &interval, Delegate &delegate, Method method) noexcept
spawns a new one-shot timer
Definition supervisor.h:388
plugin::resources_plugin_t * resources
non-owning pointer to resources plugin
Definition actor_base.h:482
void init_continue() noexcept
polls plugins whether they completed initialization.
timers_map_t timers_map
timer-id to timer-handler map
Definition actor_base.h:497
virtual void init_start() noexcept
starts initialization procedure
std::uint32_t continuation_mask
set of currently processing states, i.e. init or shutdown
Definition actor_base.h:509
virtual void shutdown_finish() noexcept
finalizes shutdown
pt::time_duration init_timeout
timeout for actor initialization (used by supervisor)
Definition actor_base.h:464
plugin::lifetime_plugin_t * lifetime
non-owning pointer to lifetime plugin
Definition actor_base.h:476
void commit_plugin_deactivation(plugin::plugin_base_t &plugin) noexcept
finishes plugin deactivation
actor_config_t config_t
injects an alias for actor_config_t
Definition actor_base.h:49
subscription_info_ptr_t subscribe(Handler &&h, const address_ptr_t &addr) noexcept
subscribes actor's handler to process messages on the specified address
Definition supervisor.h:407
pt::time_duration shutdown_timeout
timeout for actor shutdown (used by supervisor)
Definition actor_base.h:467
static const constexpr std::uint32_t AUTOSHUTDOWN_SUPERVISOR
flag to mark, that actor trigger supervisor shutdown
Definition actor_base.h:396
void on_unsubscription(message::unsubscription_t &message) noexcept
propagates unsubscription message to corresponding actors
virtual void do_shutdown(const extended_error_ptr_t &reason={}) noexcept
convenient method to send actor's supervisor shutdown trigger message
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 > plugins_list_t
the default list of plugins for an actor
Definition actor_base.h:70
auto make_response(Request &message, Args &&...args)
makes response to the request, but does not send it.
Definition supervisor.h:599
void route(const address_ptr_t &addr, const address_ptr_t &next_addr, Args &&...args)
routes message to the destination address, then to the next address
Definition supervisor.h:372
void on_subscription(message::subscription_t &message) noexcept
propagates subscription message to corresponding actors
requests_t active_requests
list of ids of active requests
Definition actor_base.h:500
static const constexpr std::uint32_t PROGRESS_SHUTDOWN
flag to mark, that actor is already executing shutdown
Definition actor_base.h:376
void unsubscribe(const handler_ptr_t &h) noexcept
initiates handler unsubscription from the default actor address
Definition actor_base.h:228
auto & access() noexcept
generic non-public fields accessor
virtual bool should_restart() const noexcept
whether spawner should create a new instance of the actor
void activate_plugins() noexcept
starts plugins activation
std::set< const std::type_index * > deactivating_plugins
set of deactivating plugin identities
Definition actor_base.h:494
std::unordered_set< request_id_t > requests_t
list of ids of active requests (type)
Definition actor_base.h:415
actor_base_t(config_t &cfg)
constructs actor and links it's supervisor
supervisor_t & get_supervisor() const noexcept
returns actor's supervisor
Definition actor_base.h:325
const address_ptr_t & get_address() const noexcept
returns actor's main address
Definition actor_base.h:322
const std::string & get_identity() const noexcept
retuns human-readable actor identity
Definition actor_base.h:370
plugins_t plugins
non-owning list of plugins
Definition actor_base.h:461
plugin_storage_ptr_t plugins_storage
opaque plugins storage (owning)
Definition actor_base.h:458
plugin::plugin_base_t * get_plugin(const std::type_index &) const noexcept
finds plugin by plugin class identity
address_ptr_t spawner_address
actor spawner address
Definition actor_base.h:449
std::set< const std::type_index * > activating_plugins
set of activating plugin identities
Definition actor_base.h:491
const extended_error_ptr_t & get_shutdown_reason() const noexcept
returns actor shutdown reason
Definition actor_base.h:363
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
virtual void on_start() noexcept
actor is fully initialized and it's supervisor has sent signal to start
virtual void do_initialize(system_context_t *ctx) noexcept
early actor initialization (pre-initialization)
void send(const address_ptr_t &addr, Args &&...args)
sends message to the destination address
Definition supervisor.h:367
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
intrusive_ptr_t< message::init_request_t > init_request
suspended init request message
Definition actor_base.h:440
plugin::address_maker_plugin_t * address_maker
non-owning pointer to address_maker plugin
Definition actor_base.h:473
void reply_with_error(Request &message, const extended_error_ptr_t &ec)
convenient method for constructing and sending error response to a request
Definition supervisor.h:611
extended_error_ptr_t shutdown_reason
explanation, why actor is been requested for shut down
Definition actor_base.h:512
state_t state
current actor state
Definition actor_base.h:470
supervisor_t * supervisor
non-owning pointer to actor's execution / infrastructure context
Definition actor_base.h:455
virtual void init_finish() noexcept
finalizes initialization
std::unordered_map< request_id_t, timer_handler_ptr_t > timers_map_t
timer-id to timer-handler map (type)
Definition actor_base.h:412
void cancel_timer(request_id_t request_id) noexcept
cancels previously started timer
void reply_to(Request &message, Args &&...args)
convenient method for constructing and sending response to a request
Definition supervisor.h:607
intrusive_ptr_t< message::shutdown_request_t > shutdown_request
suspended shutdown request message
Definition actor_base.h:443
virtual bool on_unlink(const address_ptr_t &server_addr) noexcept
notification, when actor has been unlinked from server actor
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
address_ptr_t address
actor address
Definition actor_base.h:446
void assign_shutdown_reason(extended_error_ptr_t reason) noexcept
helper-method, which assigns shutdown reason if it isn't set
void unsubscribe(Handler &&h, address_ptr_t &addr) noexcept
unsubscribes actor's handler from process messages on the specified address
Definition supervisor.h:507
std::enable_if_t< std::is_member_function_pointer_v< Handler >||std::is_base_of_v< handler_base_t, Handler > > is_handler
SFINAE handler detector.
Definition actor_base.h:60
std::string identity
actor identity, which might have some meaning for developers
Definition actor_base.h:452
CRTP actor config builder.
Definition actor_config.h:92
basic actor configuration: init and shutdown timeouts, etc.
Definition actor_config.h:62
create actor's addresses
Definition address_maker.h:24
manages actors init and shutdown procedures
Definition init_shutdown.h:22
manages all actor subscriptions (i.e. from plugins or actor itself).
Definition lifetime.h:21
base class for all actor plugins
Definition plugin_base.h:23
handy access to registry_t, for name registration and discovery
Definition registry.h:35
"lock" for external resources
Definition resources.h:39
allows custom (actor) subscriptions and it is responsible for starting actor when it receives message...
Definition starter.h:19
Holds and classifies message handlers on behalf of supervisor.
Definition subscription.h:30
The system context holds root supervisor_t (intrusive pointer) and may be loop-related details in der...
Definition system_context.h:32