actor_config.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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 <deque>
  8. #include <tuple>
  9. #include <functional>
  10. #include <memory>
  11. #include "arc.hpp"
  12. #include "plugins.h"
  13. #include "policy.h"
  14. #include "forward.hpp"
  15. namespace rotor {
  16. /** \brief list of raw plugin pointers*/
  17. using plugins_t = std::deque<plugin::plugin_base_t *>;
  18. /** \struct plugin_storage_base_t
  19. * \brief abstract item to store plugins inside actor */
  20. struct plugin_storage_base_t {
  21. virtual ~plugin_storage_base_t() {}
  22. /** \brief returns list of plugins pointers from the storage */
  23. virtual plugins_t get_plugins() noexcept = 0;
  24. };
  25. /** \brief smaprt pointer for {@link plugin_storage_base_t} */
  26. using plugin_storage_ptr_t = std::unique_ptr<plugin_storage_base_t>;
  27. /** \brief templated plugin storage implementation */
  28. template <typename PluginList> struct plugin_storage_t : plugin_storage_base_t {
  29. plugins_t get_plugins() noexcept override {
  30. plugins_t plugins;
  31. add_plugin(plugins);
  32. return plugins;
  33. }
  34. private:
  35. PluginList plugin_list;
  36. template <size_t Index = 0> void add_plugin(plugins_t &plugins) noexcept {
  37. plugins.emplace_back(&std::get<Index>(plugin_list));
  38. if constexpr (Index + 1 < std::tuple_size_v<PluginList>) {
  39. add_plugin<Index + 1>(plugins);
  40. }
  41. }
  42. };
  43. /** \struct actor_config_t
  44. * \brief basic actor configuration: init and shutdown timeouts, etc.
  45. */
  46. struct actor_config_t {
  47. /** \brief constructs {@link plugin_storage_ptr_t} (type) */
  48. using plugins_constructor_t = std::function<plugin_storage_ptr_t()>;
  49. /** \brief constructs {@link plugin_storage_ptr_t} */
  50. plugins_constructor_t plugins_constructor;
  51. /** \brief raw pointer to {@link supervisor_t} */
  52. supervisor_t *supervisor;
  53. /** \brief max actor initialization time */
  54. pt::time_duration init_timeout;
  55. /** \brief max actor shutdown time */
  56. pt::time_duration shutdown_timeout;
  57. /** \brief constructs actor_config_t from raw supervisor pointer */
  58. actor_config_t(supervisor_t *supervisor_) : supervisor{supervisor_} {}
  59. };
  60. /** \brief CRTP actor config builder */
  61. template <typename Actor> struct actor_config_builder_t {
  62. /** \brief final builder class */
  63. using builder_t = typename Actor::template config_builder_t<Actor>;
  64. /** \brief final config class */
  65. using config_t = typename Actor::config_t;
  66. /** \brief intrusive pointer to actor */
  67. using actor_ptr_t = intrusive_ptr_t<Actor>;
  68. /** \brief actor post-consturctor callback type
  69. *
  70. * For example, supervisor on_init() is invoked early (right after instantiation)
  71. *
  72. */
  73. using install_action_t = std::function<void(actor_ptr_t &)>;
  74. /** \brief bit mask for init timeout validation */
  75. constexpr static const std::uint32_t INIT_TIMEOUT = 1 << 0;
  76. /** \brief bit mask for shutdown timeout validation */
  77. constexpr static const std::uint32_t SHUTDOWN_TIMEOUT = 1 << 1;
  78. /** \brief bit mask for all required fields */
  79. constexpr static const std::uint32_t requirements_mask = INIT_TIMEOUT | SHUTDOWN_TIMEOUT;
  80. /** \brief post-construction callback */
  81. install_action_t install_action;
  82. /** \brief raw pointer to `supervisor_t` (is `null` for top-level supervisors) */
  83. supervisor_t *supervisor;
  84. /** \brief refernce to `system_context_t` */
  85. system_context_t &system_context;
  86. /** \brief the currently build config */
  87. config_t config;
  88. /** \brief required fields mask (used for validation) */
  89. std::uint32_t mask = builder_t::requirements_mask;
  90. /** \brief ctor with install action and raw pointer to supervisor */
  91. actor_config_builder_t(install_action_t &&action_, supervisor_t *supervisor_);
  92. /** \brief ctor with install action and pointer to `system_context_t` */
  93. actor_config_builder_t(install_action_t &&action_, system_context_t &system_context_)
  94. : install_action{std::move(action_)}, supervisor{nullptr}, system_context{system_context_}, config{nullptr} {
  95. init_ctor();
  96. }
  97. /** \brief setter for init and shutdown timeout */
  98. builder_t &&timeout(const pt::time_duration &timeout) &&noexcept {
  99. config.init_timeout = config.shutdown_timeout = timeout;
  100. mask = (mask & (~INIT_TIMEOUT & ~SHUTDOWN_TIMEOUT));
  101. return std::move(*static_cast<builder_t *>(this));
  102. }
  103. /** \brief setter for init timeout */
  104. builder_t &&init_timeout(const pt::time_duration &timeout) &&noexcept {
  105. config.init_timeout = timeout;
  106. mask = (mask & ~INIT_TIMEOUT);
  107. return std::move(*static_cast<builder_t *>(this));
  108. }
  109. /** \brief setter for shutdown timeout */
  110. builder_t &&shutdown_timeout(const pt::time_duration &timeout) &&noexcept {
  111. config.shutdown_timeout = timeout;
  112. mask = (mask & ~SHUTDOWN_TIMEOUT);
  113. return std::move(*static_cast<builder_t *>(this));
  114. }
  115. /** \brief checks whether config is valid, i.e. all necessary fields are set */
  116. virtual bool validate() noexcept { return mask ? false : true; }
  117. /** \brief constructs actor from the current config */
  118. actor_ptr_t finish() &&;
  119. private:
  120. void init_ctor() noexcept {
  121. config.plugins_constructor = []() -> plugin_storage_ptr_t {
  122. using plugins_list_t = typename Actor::plugins_list_t;
  123. using storage_t = plugin_storage_t<plugins_list_t>;
  124. return std::make_unique<storage_t>();
  125. };
  126. }
  127. };
  128. } // namespace rotor