registry.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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 "actor_base.h"
  8. #include "messages.hpp"
  9. #include <unordered_map>
  10. #include <set>
  11. #include <list>
  12. #if defined(_MSC_VER)
  13. #pragma warning(push)
  14. #pragma warning(disable : 4251)
  15. #endif
  16. namespace rotor {
  17. /** \struct registry_t
  18. * \brief keeps name-to-service_address mapping at runtime
  19. *
  20. * The class solves the following problem: one actor needs to know
  21. * somehow the address of other actor. Instead of tightly couple
  22. * them, i.e. manually binding addresses, it is possible to just
  23. * take the registry everywhere and ask it (or register there)
  24. * just on actor startup (initialization)
  25. *
  26. * The "server-actor" must register it's address first. The name
  27. * must be unique (in the scope of registry); the same address
  28. * can be registered on different names, if need. It is good
  29. * practice to unregister addresses when actor is going to be
  30. * shutdown (it is done by {@link plugin::registry_plugin_t}).
  31. * It is possible to unregister single name, or all
  32. * names associated with an address.
  33. *
  34. * The discovery response returned to "client-actor" might contain
  35. * error code if there is no address associated with the asked name.
  36. *
  37. * The actor has syncronization facilities, i.e. it is possible to
  38. * ask the actor to notify when some name has been registered
  39. * (discovery promise/future).
  40. *
  41. */
  42. struct ROTOR_API registry_t : public actor_base_t {
  43. using actor_base_t::actor_base_t;
  44. void configure(plugin::plugin_base_t &plugin) noexcept override;
  45. /** \brief registers address on the service. Fails, if the name already exists */
  46. virtual void on_reg(message::registration_request_t &request) noexcept;
  47. /** \brief deregisters the name in the registry */
  48. virtual void on_dereg_service(message::deregistration_service_t &message) noexcept;
  49. /** \brief deregisters all names associated with the service address */
  50. virtual void on_dereg(message::deregistration_notify_t &message) noexcept;
  51. /** \brief returns service address associated with the name or error */
  52. virtual void on_discovery(message::discovery_request_t &request) noexcept;
  53. /** \brief notify the requestee when service name/address becomes available */
  54. virtual void on_promise(message::discovery_promise_t &request) noexcept;
  55. /** \brief cancels previously asked discovery promise */
  56. virtual void on_cancel(message::discovery_cancel_t &notify) noexcept;
  57. /** \brief generic non-public fields accessor */
  58. template <typename T> auto &access() noexcept;
  59. protected:
  60. /** \brief intrusive pointer to discovery promise message (type) */
  61. using promise_ptr_t = intrusive_ptr_t<message::discovery_promise_t>;
  62. /** \brief list of intrusive pointers to discovery promise messages (type) */
  63. using promises_list_t = std::list<promise_ptr_t>;
  64. /** \brief name-to-address mapping type */
  65. using registered_map_t = std::unordered_map<std::string, address_ptr_t>;
  66. /** \brief set of registered names type (for single address) */
  67. using registered_names_t = std::set<std::string>;
  68. /** \brief service address to registered names mapping type */
  69. using reverse_map_t = std::unordered_map<address_ptr_t, registered_names_t>;
  70. /** \brief name-to-address mapping */
  71. registered_map_t registered_map;
  72. /** \brief address-to-list_of_names mapping */
  73. reverse_map_t reverse_map;
  74. /** \brief list of intrusive pointers to discovery promise messages */
  75. promises_list_t promises;
  76. };
  77. } // namespace rotor
  78. #if defined(_MSC_VER)
  79. #pragma warning(pop)
  80. #endif