child_manager.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #pragma once
  2. //
  3. // Copyright (c) 2019-2022 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
  4. //
  5. // Distributed under the MIT Software License
  6. //
  7. #include "plugin_base.h"
  8. #include <unordered_set>
  9. #include "rotor/detail/child_info.h"
  10. #if defined(_MSC_VER)
  11. #pragma warning(push)
  12. #pragma warning(disable : 4251)
  13. #endif
  14. namespace rotor::plugin {
  15. /** \struct child_manager_plugin_t
  16. *
  17. * \brief supervisor's plugin for child-actors housekeeping
  18. *
  19. * The plugin is responsible for child actors creation, initialization
  20. * and shutdown. The supervisor policy is also handled here, e.g.
  21. * if an child-actor fails to initialize self, the supervisor
  22. * might shutdown self.
  23. *
  24. */
  25. struct ROTOR_API child_manager_plugin_t : public plugin_base_t {
  26. using plugin_base_t::plugin_base_t;
  27. /** The plugin unique identity to allow further static_cast'ing*/
  28. static const void *class_identity;
  29. const void *identity() const noexcept override;
  30. void activate(actor_base_t *actor) noexcept override;
  31. void deactivate() noexcept override;
  32. /** \brief pre-initializes child and sends create_child message to the supervisor */
  33. virtual void create_child(const actor_ptr_t &actor) noexcept;
  34. /** \brief records spawner (via generating a new address) and sends
  35. * spawn_actor_t message to the supersior */
  36. virtual void spawn(factory_t factory, const pt::time_duration &period, restart_policy_t policy, size_t max_attempts,
  37. bool escalate) noexcept;
  38. /** \brief removes the child from the supervisor
  39. *
  40. * If there was an error, the supervisor might trigger shutdown self (in accordance with policy)
  41. *
  42. * Otherwise, if all is ok, it continues the supervisor initialization
  43. */
  44. virtual void remove_child(const actor_base_t &actor) noexcept;
  45. /** \brief reaction on child shutdown failure
  46. *
  47. * By default it is forwarded to system context, which terminates program by default
  48. */
  49. virtual void on_shutdown_fail(actor_base_t &actor, const extended_error_ptr_t &ec) noexcept;
  50. /** \brief sends initialization request upon actor creation message */
  51. virtual void on_create(message::create_actor_t &message) noexcept;
  52. /** \brief reaction on (maybe unsuccessful) init confirmatinon
  53. *
  54. * Possibilities:
  55. * - shutdown child
  56. * - shutdown self (supervisor)
  57. * - continue init
  58. *
  59. */
  60. virtual void on_init(message::init_response_t &message) noexcept;
  61. /** \brief reaction on shutdown trigger
  62. *
  63. * Possibilities:
  64. * - shutdown self (supervisor), via shutdown request
  65. * - shutdown self (supervisor) directly, if there is no root supervisor
  66. * - shutdown via request for a child
  67. *
  68. */
  69. virtual void on_shutdown_trigger(message::shutdown_trigger_t &message) noexcept;
  70. /** \brief reaction on shutdown confirmation (i.e. perform some cleanings) */
  71. virtual void on_shutdown_confirm(message::shutdown_response_t &message) noexcept;
  72. /** \brief actually attempts to spawn a new actor via spawner */
  73. virtual void on_spawn(message::spawn_actor_t &message) noexcept;
  74. bool handle_init(message::init_request_t *) noexcept override;
  75. bool handle_shutdown(message::shutdown_request_t *) noexcept override;
  76. void handle_start(message::start_trigger_t *message) noexcept override;
  77. bool handle_unsubscription(const subscription_point_t &point, bool external) noexcept override;
  78. /** \brief generic non-public fields accessor */
  79. template <typename T> auto &access() noexcept;
  80. private:
  81. using actors_map_t = std::unordered_map<address_ptr_t, detail::child_info_ptr_t>;
  82. using spawning_map_t = std::unordered_map<request_id_t, detail::child_info_ptr_t>;
  83. bool has_initializing() const noexcept;
  84. void init_continue() noexcept;
  85. void request_shutdown(const extended_error_ptr_t &ec) noexcept;
  86. void cancel_init(const actor_base_t *child) noexcept;
  87. void request_shutdown(detail::child_info_t &child_state, const extended_error_ptr_t &ec) noexcept;
  88. void on_spawn_timer(request_id_t timer_id, bool cancelled) noexcept;
  89. size_t active_actors() noexcept;
  90. /** \brief type for keeping list of initializing actors (during supervisor inititalization) */
  91. using initializing_actors_t = std::unordered_set<address_ptr_t>;
  92. /** \brief local address to local actor (intrusive pointer) mapping */
  93. actors_map_t actors_map;
  94. spawning_map_t spawning_map;
  95. };
  96. } // namespace rotor::plugin
  97. #if defined(_MSC_VER)
  98. #pragma warning(pop)
  99. #endif