delivery.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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 "plugin_base.h"
  8. #include <string>
  9. namespace rotor::plugin {
  10. /** \struct local_delivery_t
  11. *
  12. * \brief basic local message delivery implementation
  13. */
  14. struct local_delivery_t {
  15. /** \brief delivers an message for self of one of child-actors (non-supervisors)
  16. *
  17. * Supervisor iterates on subscriptions (handlers) on the message destination adddress:
  18. *
  19. * - If the handler is local (i.e. it's actor belongs to the same supervisor),
  20. * - Otherwise the message is forwarded for delivery for the foreign supervisor,
  21. * which owns the handler.
  22. *
  23. */
  24. static void delivery(message_ptr_t &message, const subscription_t::joint_handlers_t &local_recipients) noexcept;
  25. };
  26. /** \struct inspected_local_delivery_t
  27. *
  28. * \brief debugging local message delivery implementation with dumping details to stdout.
  29. */
  30. struct inspected_local_delivery_t {
  31. /** \brief stringifies the message into human-readable debug form */
  32. static std::string identify(message_base_t *message, int32_t threshold) noexcept;
  33. /** \brief delivers the message to the recipients, possbily dumping it to console */
  34. static void delivery(message_ptr_t &message, const subscription_t::joint_handlers_t &local_recipients) noexcept;
  35. };
  36. #if defined(NDEBUG) || defined(ROTOR_DEBUG_DELIVERY)
  37. using default_local_delivery_t = local_delivery_t;
  38. #else
  39. using default_local_delivery_t = inspected_local_delivery_t;
  40. #endif
  41. /** \struct delivery_plugin_base_t
  42. *
  43. * \brief base implementation for messages delivery plugin
  44. */
  45. struct delivery_plugin_base_t : public plugin_base_t {
  46. using plugin_base_t::plugin_base_t;
  47. ~delivery_plugin_base_t();
  48. /** \brief main messages dispatcher interface */
  49. virtual void process() noexcept = 0;
  50. void activate(actor_base_t *actor) noexcept override;
  51. protected:
  52. /** \brief non-owning raw pointer of supervisor's messages queue */
  53. messages_queue_t *queue = nullptr;
  54. /** \brief non-owning raw pointer to supervisor's main address */
  55. address_t *address = nullptr;
  56. /** \brief non-owning raw pointer to supervisor's subscriptions map */
  57. subscription_t *subscription_map;
  58. };
  59. /** \brief templated message delivery plugin, to allow local message delivery be customized */
  60. template <typename LocalDelivery = local_delivery_t> struct delivery_plugin_t : public delivery_plugin_base_t {
  61. using delivery_plugin_base_t::delivery_plugin_base_t;
  62. /** The plugin unique identity to allow further static_cast'ing*/
  63. static const void *class_identity;
  64. const void *identity() const noexcept override { return class_identity; }
  65. void process() noexcept override;
  66. };
  67. template <typename LocalDelivery>
  68. const void *
  69. delivery_plugin_t<LocalDelivery>::class_identity = static_cast<const void *>(typeid(local_delivery_t).name());
  70. } // namespace rotor::plugin