child_manager.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #pragma once
  2. //
  3. // Copyright (c) 2019-2020 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. namespace rotor::plugin {
  10. /** \struct child_manager_plugin_t
  11. *
  12. * \brief supervisor's plugin for child-actors housekeeping
  13. *
  14. * The plugin is responsible for child actors creation, initialization
  15. * and shutdown. The supervisor policy is also handled here, e.g.
  16. * if an child-actor fails to initialize self, the supervisor
  17. * might shutdown self.
  18. *
  19. */
  20. struct child_manager_plugin_t : public plugin_base_t {
  21. using plugin_base_t::plugin_base_t;
  22. /** The plugin unique identity to allow further static_cast'ing*/
  23. static const void *class_identity;
  24. const void *identity() const noexcept override;
  25. void activate(actor_base_t *actor) noexcept override;
  26. void deactivate() noexcept override;
  27. /** \brief pre-initializes child and sends create_child message to the supervisor */
  28. virtual void create_child(const actor_ptr_t &actor) noexcept;
  29. /** \brief removes the child from the supervisor
  30. *
  31. * If there was an error, the supervisor might trigger shutdown self (in accordance with policy)
  32. *
  33. * Otherwise, if all is ok, it continues the supervisor initialization
  34. */
  35. virtual void remove_child(const actor_base_t &actor) noexcept;
  36. /** \brief reaction on child shutdown failure
  37. *
  38. * By default it is forwarded to system context, which terminates program by default
  39. */
  40. virtual void on_shutdown_fail(actor_base_t &actor, const std::error_code &ec) noexcept;
  41. /** \brief sends initialization request upon actor creation message */
  42. virtual void on_create(message::create_actor_t &message) noexcept;
  43. /** \brief reaction on (maybe unsuccessful) init confirmatinon
  44. *
  45. * Possibilities:
  46. * - shutdown child
  47. * - shutdown self (supervisor)
  48. * - continue init
  49. *
  50. */
  51. virtual void on_init(message::init_response_t &message) noexcept;
  52. /** \brief reaction on shutdown trigger
  53. *
  54. * Possibilities:
  55. * - shutdown self (supervisor), via shutdown request
  56. * - shutdown self (supervisor) directly, if there is no root supervisor
  57. * - shutdown via request for a child
  58. *
  59. */
  60. virtual void on_shutdown_trigger(message::shutdown_trigger_t &message) noexcept;
  61. /** \brief reacion on shutdown confirmation (i.e. perform some cleanings) */
  62. virtual void on_shutdown_confirm(message::shutdown_response_t &message) noexcept;
  63. /** \brief answers about actor's state, identified by it's address
  64. *
  65. * If there is no information about the address (including the case when an actor
  66. * is not yet created or already destroyed), then it replies with `UNKNOWN` status.
  67. *
  68. * It replies to the address specified to the `reply_addr` specified in
  69. * the message {@link payload::state_request_t}.
  70. *
  71. */
  72. virtual void on_state_request(message::state_request_t &message) noexcept;
  73. bool handle_init(message::init_request_t *) noexcept override;
  74. bool handle_shutdown(message::shutdown_request_t *) noexcept override;
  75. void handle_start(message::start_trigger_t *message) noexcept override;
  76. bool handle_unsubscription(const subscription_point_t &point, bool external) noexcept override;
  77. /** \brief generic non-public fields accessor */
  78. template <typename T> auto &access() noexcept;
  79. private:
  80. enum class request_state_t { NONE, SENT, CONFIRMED };
  81. struct actor_state_t {
  82. /** \brief intrusive pointer to actor */
  83. actor_ptr_t actor;
  84. template <typename Actor> actor_state_t(Actor &&act) noexcept : actor{std::forward<Actor>(act)} {}
  85. bool initialized = false;
  86. bool strated = false;
  87. request_state_t shutdown = request_state_t::NONE;
  88. };
  89. bool has_initializing() const noexcept;
  90. void init_continue() noexcept;
  91. void request_shutdown() noexcept;
  92. void cancel_init(const actor_base_t *child) noexcept;
  93. void request_shutdown(actor_state_t &actor_state) noexcept;
  94. using actors_map_t = std::unordered_map<address_ptr_t, actor_state_t>;
  95. /** \brief type for keeping list of initializing actors (during supervisor inititalization) */
  96. using initializing_actors_t = std::unordered_set<address_ptr_t>;
  97. bool postponed_init = false;
  98. /** \brief local address to local actor (intrusive pointer) mapping */
  99. actors_map_t actors_map;
  100. };
  101. } // namespace rotor::plugin