address_mapping.h 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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 "arc.hpp"
  8. #include "subscription.h"
  9. #include <unordered_map>
  10. #include <vector>
  11. #if defined(_MSC_VER)
  12. #pragma warning(push)
  13. #pragma warning(disable : 4251)
  14. #endif
  15. namespace rotor {
  16. /** \struct address_mapping_t
  17. * \brief NAT mechanism for `rotor`
  18. *
  19. * It plays the similar role as https://en.wikipedia.org/wiki/Network_address_translation
  20. * in routers, i.e. the original message (request) is dispatched from different address
  21. * then source actor. It's needed for supervising it.
  22. *
  23. * The `address_mapping_t` does not hold the original reply address. That kind of
  24. * mapping is done on `per-request` basis. The `address_mapping_t` performs only
  25. * `per-message-type` mapping.
  26. *
  27. */
  28. struct ROTOR_API address_mapping_t {
  29. /** \brief associates temporal destination point with actor's message type
  30. *
  31. * An actor is able to process message type identified by `message`. So,
  32. * the temporal subscription point (handler and temporal address) will
  33. * be associated with the actor/message type pair.
  34. *
  35. * In the routing the temporal destination address is usually some
  36. * supervisor's address.
  37. *
  38. */
  39. void set(actor_base_t &actor, const subscription_info_ptr_t &info) noexcept;
  40. /** \brief returns temporal destination address for the actor/message type */
  41. address_ptr_t get_mapped_address(actor_base_t &actor, const void *) noexcept;
  42. /** \brief iterates on all subscriptions for an actor */
  43. template <typename Fn> void each_subscription(const actor_base_t &actor, Fn &&fn) const noexcept {
  44. auto it_mappings = actor_map.find(static_cast<const void *>(&actor));
  45. for (auto it : it_mappings->second) {
  46. fn(it.second);
  47. }
  48. }
  49. /** \brief checks whether an actor has any subscriptions */
  50. bool has_subscriptions(const actor_base_t &actor) const noexcept;
  51. /** \brief returns true if there is no any subscription for any actor */
  52. bool empty() const noexcept { return actor_map.empty(); }
  53. /** \brief forgets subscription point */
  54. void remove(const subscription_point_t &point) noexcept;
  55. private:
  56. using point_map_t = std::unordered_map<const void *, subscription_info_ptr_t>;
  57. using actor_map_t = std::unordered_map<const void *, point_map_t>;
  58. actor_map_t actor_map;
  59. };
  60. } // namespace rotor
  61. #if defined(_MSC_VER)
  62. #pragma warning(pop)
  63. #endif