address_mapping.h 2.3 KB

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