messages.hpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  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 "address.hpp"
  8. #include "message.h"
  9. #include "state.h"
  10. #include "request.hpp"
  11. #include "subscription_point.h"
  12. #include "forward.hpp"
  13. #include "extended_error.h"
  14. #if defined(_MSC_VER)
  15. #pragma warning(push)
  16. #pragma warning(disable : 4251)
  17. #endif
  18. namespace rotor {
  19. /// namespace for rotor core payloads
  20. namespace payload {
  21. /** \struct initialize_confirmation_t
  22. * \brief Message with this payload is sent from an actor to its supervisor to
  23. * confirm successful initialization
  24. */
  25. struct initialize_confirmation_t {};
  26. /** \struct initialize_actor_t
  27. * \brief Message with this payload is sent from a supervisor to an actor as
  28. * initialization request
  29. */
  30. struct initialize_actor_t {
  31. /** \brief link to response payload type */
  32. using response_t = initialize_confirmation_t;
  33. };
  34. /** \struct start_actor_t
  35. * \brief Message with this payload is sent from a supervisor to an actor as
  36. * start confirmation
  37. */
  38. struct start_actor_t {};
  39. /** \struct create_actor_t
  40. * \brief Message with this payload is sent to supervisor when an actor is
  41. * created (constructed).
  42. *
  43. * The message is needed for internal {@link supervisor_t} housekeeping.
  44. *
  45. */
  46. struct create_actor_t {
  47. /** \brief the intrusive pointer to created actor */
  48. actor_ptr_t actor;
  49. /** \brief maximum time for actor initialization
  50. *
  51. * If an actor isn't able to confirm initialization in time, it
  52. * will be asked to shutdown (default behavior)
  53. *
  54. */
  55. pt::time_duration timeout;
  56. };
  57. /** \struct spawn_actor_t
  58. * \brief Message with this payload is sent to supervisor when
  59. * spawner should create new actor instance.
  60. *
  61. * The message is needed for internal {@link spawner_t} housekeeping.
  62. *
  63. */
  64. struct spawn_actor_t {
  65. /** \brief identifies the spawner */
  66. address_ptr_t spawner_address;
  67. };
  68. /** \struct shutdown_trigger_t
  69. * \brief Message with this payload is sent to ask an actor's supervisor
  70. * to initiate shutdown procedure.
  71. *
  72. */
  73. struct shutdown_trigger_t {
  74. /** \brief the actor to be shut down */
  75. address_ptr_t actor_address;
  76. /** \brief shutdown reason */
  77. extended_error_ptr_t reason;
  78. /** \brief constructs shutdown trigger for the actor, defined with address, and the shutdown reason */
  79. template <typename Address, typename Reason>
  80. shutdown_trigger_t(Address &&address_, Reason &&reason_) noexcept
  81. : actor_address(std::forward<Address>(address_)), reason(std::forward<Reason>(reason_)) {}
  82. };
  83. /** \struct shutdown_confirmation_t
  84. * \brief Message with this payload is sent from an actor to its supervisor to
  85. * confirm successful shutdown.
  86. */
  87. struct shutdown_confirmation_t {};
  88. /** \struct shutdown_request_t
  89. * \brief Message with this payload is sent from a supervisor to an actor as
  90. * shutdown request
  91. */
  92. struct shutdown_request_t {
  93. /** \brief link to response payload type */
  94. using response_t = shutdown_confirmation_t;
  95. /** \brief constructs shutdown request with shutdown reason */
  96. template <typename Reason>
  97. explicit shutdown_request_t(Reason &&reason_) noexcept : reason(std::forward<Reason>(reason_)) {}
  98. /** \brief shutdown reason */
  99. extended_error_ptr_t reason;
  100. };
  101. /** \struct handler_call_t
  102. * \brief Message with this payload is forwarded to the handler's supervisor for
  103. * the delivery of the original message.
  104. *
  105. * An `address` in `rotor` is always generated by a supervisor. All messages to the
  106. * address are initially pre-processed by the supervisor: if the destination handler
  107. * supervisor is the same as the message address supervisor, the handler is invoked
  108. * immediately. Otherwise, if a handler belongs to different supervisor (i.e. may
  109. * be to different event loop), then the delivery of the message is forwarded to
  110. * that supervisor.
  111. *
  112. */
  113. struct handler_call_t {
  114. /** \brief The original message (intrusive pointer) sent to an address */
  115. message_ptr_t orig_message;
  116. /** \brief The handler (intrusive pointer) on some external supervisor,
  117. * which can process the original message */
  118. handler_ptr_t handler;
  119. };
  120. /** \struct external_subscription_t
  121. * \brief Message with this payload is forwarded to the target address supervisor
  122. * for recording subscription in the external (foreign) handler
  123. *
  124. * When a supervisor process subscription requests from it's (local) actors, it
  125. * can found that the `target_address` belongs to some other (external/foreign)
  126. * supervisor. In that case the subscription is forwarded to the external
  127. * supervisor.
  128. *
  129. */
  130. struct external_subscription_t {
  131. /** \brief subscription details */
  132. subscription_point_t point;
  133. };
  134. /** \struct subscription_confirmation_t
  135. * \brief Message with this payload is sent from a supervisor to an actor when
  136. * successful subscription to the `target` address occurs.
  137. *
  138. * The message is needed for internal {@link actor_base_t} housekeeping.
  139. *
  140. */
  141. struct subscription_confirmation_t {
  142. /** \brief subscription details */
  143. subscription_point_t point;
  144. };
  145. /** \struct external_unsubscription_t
  146. * \brief Message with this payload is forwarded to the target address supervisor
  147. * for recording unsubscription in the external (foreign) handler.
  148. *
  149. * The message is symmetrical to the {@link external_subscription_t}.
  150. *
  151. */
  152. struct external_unsubscription_t {
  153. /** \brief subscription details */
  154. subscription_point_t point;
  155. };
  156. /** \struct commit_unsubscription_t
  157. * \brief Message with this payload is sent to the target address supervisor
  158. * for confirming unsubscription in the external (foreign) handler.
  159. *
  160. * The message is an actor-reply to {@link external_subscription_t} request.
  161. *
  162. */
  163. struct commit_unsubscription_t {
  164. /** \brief subscription details */
  165. subscription_point_t point;
  166. };
  167. /** \struct unsubscription_confirmation_t
  168. * \brief Message with this payload is sent from a supervisor to an actor with
  169. * confirmation that `point` is no longer active (subscribed).`
  170. */
  171. struct unsubscription_confirmation_t {
  172. /** \brief subscription details */
  173. subscription_point_t point;
  174. };
  175. /** \struct registration_response_t
  176. * \brief Successful registration response (no content)
  177. */
  178. struct registration_response_t {};
  179. /** \struct registration_request_t
  180. * \brief "name - >service address mapping" request
  181. */
  182. struct registration_request_t {
  183. /** \brief link to registration response payload type */
  184. using response_t = registration_response_t;
  185. /** \brief (unique) name of the service address in the registry */
  186. std::string service_name;
  187. /** \brief actual service address */
  188. address_ptr_t service_addr;
  189. };
  190. /** \struct deregistration_notify_t
  191. * \brief deregistration notification for all names associated
  192. * with service address
  193. */
  194. struct deregistration_notify_t {
  195. /** \brief service address for deregistration */
  196. address_ptr_t service_addr;
  197. };
  198. /** \struct deregistration_service_t
  199. * \brief removes single service by name from a registry
  200. */
  201. struct deregistration_service_t {
  202. /** \brief the name of the service address to be removed for a registry */
  203. std::string service_name;
  204. };
  205. /** \struct discovery_reply_t
  206. * \brief successful result of service discovery
  207. */
  208. struct discovery_reply_t {
  209. /** \brief the service address found by name in a registry */
  210. address_ptr_t service_addr;
  211. };
  212. /** \struct discovery_request_t
  213. * \brief discover service by name in a registry
  214. */
  215. struct discovery_request_t {
  216. /** \brief link to discovery response payload type */
  217. using response_t = discovery_reply_t;
  218. /** \brief the service name to be looked in a registry */
  219. std::string service_name;
  220. };
  221. /** \struct discovery_future_t
  222. * \brief delayed discovery response as soon as an address has been registered
  223. */
  224. struct discovery_future_t {
  225. /** \brief the service address found by name in a registry */
  226. address_ptr_t service_addr;
  227. };
  228. /** \struct discovery_promise_t
  229. * \brief ask registry for {@link discovery_future_t} when the target
  230. * service name has been registered
  231. */
  232. struct discovery_promise_t {
  233. /** \brief link to discovery future payload type */
  234. using response_t = discovery_future_t;
  235. /** \brief the service name to be looked in a registry */
  236. std::string service_name;
  237. };
  238. /** \struct link_response_t
  239. * \brief successful confirmation to {@link link_request_t}
  240. */
  241. struct link_response_t {};
  242. /** \struct link_request_t
  243. * \brief requests target actor to be linked with the current one
  244. */
  245. struct link_request_t {
  246. /** \brief link to link response payload type */
  247. using response_t = link_response_t;
  248. /** \brief wait until target server (actor) starts, only then reply to the source actor */
  249. bool operational_only;
  250. };
  251. /** \struct unlink_notify_t
  252. * \brief "client" notifies "server" that the connection has been closed
  253. * from its side
  254. */
  255. struct unlink_notify_t {
  256. /** \brief client actor address in unlinking */
  257. address_ptr_t client_addr;
  258. };
  259. /** \struct unlink_request_t
  260. * \brief "server" asks "client" for closing connection
  261. */
  262. struct unlink_request_t {
  263. /** \brief link to unlink response payload type */
  264. using response_t = unlink_notify_t;
  265. /** \brief server actor address in unlinking */
  266. address_ptr_t server_addr;
  267. };
  268. } // namespace payload
  269. /// namespace for rotor core messages (which just transform payloads)
  270. namespace message {
  271. // subscription-related
  272. /** \brief unsubscription confirmation message */
  273. using unsubscription_t = message_t<payload::unsubscription_confirmation_t>;
  274. /** \brief external unsubscription message */
  275. using unsubscription_external_t = message_t<payload::external_unsubscription_t>;
  276. /** \brief subscription confirmation message */
  277. using subscription_t = message_t<payload::subscription_confirmation_t>;
  278. /** \brief external subscription message */
  279. using external_subscription_t = message_t<payload::external_subscription_t>;
  280. /** \brief unsubscription commit message */
  281. using commit_unsubscription_t = message_t<payload::commit_unsubscription_t>;
  282. /** \brief delivers foreign message to the actor's supervisor
  283. *
  284. * Upon delivery the appropriate handler on the actor will be thread-safely
  285. * called by it's supervisor
  286. */
  287. using handler_call_t = message_t<payload::handler_call_t>;
  288. // lifetime-related
  289. /** \brief actor initialization request */
  290. using init_request_t = request_traits_t<payload::initialize_actor_t>::request::message_t;
  291. /** \brief actor initialization response */
  292. using init_response_t = request_traits_t<payload::initialize_actor_t>::response::message_t;
  293. /** \brief actor start trigger */
  294. using start_trigger_t = message_t<payload::start_actor_t>;
  295. /** \brief actor shutdown trigger */
  296. using shutdown_trigger_t = message_t<payload::shutdown_trigger_t>;
  297. /** \brief actor shutdown request */
  298. using shutdown_request_t = request_traits_t<payload::shutdown_request_t>::request::message_t;
  299. /** \brief actor shutdown response */
  300. using shutdown_response_t = request_traits_t<payload::shutdown_request_t>::response::message_t;
  301. /** \brief supervisor's message upon actor instantiation */
  302. using create_actor_t = message_t<payload::create_actor_t>;
  303. /** \brief supervisor's message to spawn new actor */
  304. using spawn_actor_t = message_t<payload::spawn_actor_t>;
  305. // registry-related
  306. /** \brief name/address registration request */
  307. using registration_request_t = request_traits_t<payload::registration_request_t>::request::message_t;
  308. /** \brief name/address registration response */
  309. using registration_response_t = request_traits_t<payload::registration_request_t>::response::message_t;
  310. /** \brief deregistration notification (from client) */
  311. using deregistration_notify_t = message_t<payload::deregistration_notify_t>;
  312. /** \brief deregistration notification (from registry-server) */
  313. using deregistration_service_t = message_t<payload::deregistration_service_t>;
  314. /** \brief name discovery request */
  315. using discovery_request_t = request_traits_t<payload::discovery_request_t>::request::message_t;
  316. /** \brief name discovery response */
  317. using discovery_response_t = request_traits_t<payload::discovery_request_t>::response::message_t;
  318. /** \brief name discovery promise (aka get response when name will be available) */
  319. using discovery_promise_t = request_traits_t<payload::discovery_promise_t>::request::message_t;
  320. /** \brief name discovery future (reply to promise) */
  321. using discovery_future_t = request_traits_t<payload::discovery_promise_t>::response::message_t;
  322. /** \brief name discovery promise cancellation */
  323. using discovery_cancel_t = request_traits_t<payload::discovery_promise_t>::cancel::message_t;
  324. // link-related
  325. /** \brief actor link request */
  326. using link_request_t = request_traits_t<payload::link_request_t>::request::message_t;
  327. /** \brief actor link response */
  328. using link_response_t = request_traits_t<payload::link_request_t>::response::message_t;
  329. /** \brief unlink notification (client is no longer interested in the link) */
  330. using unlink_notify_t = message_t<payload::unlink_notify_t>;
  331. /** \brief unlink request (server is asking client to cancel link) */
  332. using unlink_request_t = request_traits_t<payload::unlink_request_t>::request::message_t;
  333. /** \brief unlink response (client confirms link cancellation) */
  334. using unlink_response_t = request_traits_t<payload::unlink_request_t>::response::message_t;
  335. } // namespace message
  336. } // namespace rotor
  337. #if defined(_MSC_VER)
  338. #pragma warning(pop)
  339. #endif