messages.hpp 13 KB

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