child_info.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #pragma once
  2. //
  3. // Copyright (c) 2022 Ivan Baidakou (basiliscos) (the dot dmol at gmail dot com)
  4. //
  5. // Distributed under the MIT Software License
  6. //
  7. #include "rotor/forward.hpp"
  8. #include "rotor/policy.h"
  9. #include <variant>
  10. #if defined(_MSC_VER)
  11. #pragma warning(push)
  12. #pragma warning(disable : 4251)
  13. #endif
  14. namespace rotor::detail {
  15. enum class shutdown_state_t { none, sent, confirmed };
  16. namespace demand {
  17. struct no {};
  18. struct now {};
  19. struct escalate_failure {};
  20. } // namespace demand
  21. using spawn_demand_t = std::variant<demand::no, demand::now, demand::escalate_failure, pt::time_duration>;
  22. /** \struct child_info_t
  23. * \brief Child actor runtime housekeeping information.
  24. *
  25. * Used by child_manager_plugin_t.
  26. *
  27. */
  28. struct ROTOR_API child_info_t : boost::intrusive_ref_counter<child_info_t, boost::thread_unsafe_counter> {
  29. /** \brief an alias for used microsec clock */
  30. using clock_t = pt::microsec_clock;
  31. /** \brief CTOR for spawner-instantiated actor */
  32. template <typename Factory>
  33. child_info_t(address_ptr_t address_, Factory &&factory_, restart_policy_t policy_ = restart_policy_t::normal_only,
  34. const pt::time_duration &restart_period_ = pt::seconds{15}, size_t max_attempts_ = 0,
  35. bool escalate_failure_ = false) noexcept
  36. : address{std::move(address_)}, factory{std::forward<Factory>(factory_)}, policy{policy_},
  37. restart_period{restart_period_}, max_attempts{max_attempts_}, escalate_failure{escalate_failure_} {}
  38. /** \brief CTOR for manually instantiated actor */
  39. template <typename Factory, typename Actor>
  40. child_info_t(address_ptr_t address_, Factory &&factory_, Actor &&actor_) noexcept
  41. : child_info_t(std::move(address_), std::forward<Factory>(factory_)) {
  42. actor = std::forward<Actor>(actor_);
  43. if (actor) {
  44. spawn_attempt();
  45. }
  46. }
  47. /** \brief recalculates the state upon spawn_attempt
  48. *
  49. * The last last_instantiation is refreshed, and may be
  50. * the child info becomes inactivated (due to restart_policy)
  51. *
  52. */
  53. void spawn_attempt() noexcept;
  54. /** \brief checks whether new actor should be spawned
  55. *
  56. * New actor can be spawned right now, a bit later,
  57. * not spawned at all possibly with triggering supersior
  58. * shutdown.
  59. *
  60. */
  61. spawn_demand_t next_spawn(bool abnormal_shutdown) noexcept;
  62. /** \brief actor's address */
  63. address_ptr_t address;
  64. /** \brief actor's factory (used by spawner) */
  65. factory_t factory;
  66. /** \brief owning reference to current actor instanance */
  67. actor_ptr_t actor;
  68. /** \brief restart policy (used by spawner) */
  69. restart_policy_t policy;
  70. /** \brief minimum amount of time between spawning attempts */
  71. pt::time_duration restart_period;
  72. /** \brief actor shutdown substate */
  73. shutdown_state_t shutdown = shutdown_state_t::none;
  74. /** \brief maximum restart attempts (used by spawner) */
  75. size_t max_attempts;
  76. /** \brief the current number of restart attempts */
  77. size_t attempts = 0;
  78. /** \brief whether the spawner is active */
  79. bool active = true;
  80. /** \brief whether an actor failure should be escalated to supersior */
  81. bool escalate_failure = false;
  82. /** \brief the timer_id when actor should be spawned */
  83. request_id_t timer_id{0};
  84. /** \brief when an actor was successfully spawned */
  85. pt::ptime last_instantiation;
  86. /** \brief whether actor is initialized */
  87. bool initialized = false;
  88. /** \brief whether actor is started */
  89. bool started = false;
  90. };
  91. using child_info_ptr_t = boost::intrusive_ptr<child_info_t>;
  92. } // namespace rotor::detail
  93. #if defined(_MSC_VER)
  94. #pragma warning(pop)
  95. #endif