delivery.h 3.1 KB

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