SObjectizer-5 Extra
retained_msg.hpp
Go to the documentation of this file.
1 /*!
2  * \file
3  * \brief Implementation of mbox which holds last sent message.
4  *
5  * \since
6  * v.1.0.3
7  */
8 
9 #pragma once
10 
11 #include <so_5_extra/error_ranges.hpp>
12 
13 #include <so_5/rt/impl/h/agent_ptr_compare.hpp>
14 #include <so_5/rt/impl/h/message_limit_internals.hpp>
15 #include <so_5/rt/impl/h/msg_tracing_helpers.hpp>
16 
17 #include <so_5/details/h/sync_helpers.hpp>
18 
19 #include <so_5/rt/h/mbox.hpp>
20 
21 #include <memory>
22 
23 namespace so_5 {
24 
25 namespace extra {
26 
27 namespace mboxes {
28 
29 namespace retained_msg {
30 
31 namespace errors {
32 
33 /*!
34  * \brief An attempt perform service request via retained message mbox.
35  *
36  * \since
37  * v.1.0.3
38  */
41 
42 
43 } /* namespace errors */
44 
45 //
46 // service_request_support_t
47 //
48 /*!
49  * \brief Indiction of service requests support for retained message mbox.
50  *
51  * \since
52  * v.1.0.3
53  */
55  {
56  //! Service requests are not supported.
57  //! This the default value for retained message mboxes.
58  disabled,
59  //! Service requests are supported.
60  enabled
61  };
62 
63 namespace details {
64 
65 /*!
66  * \brief A helper type which is a collection of type parameters.
67  *
68  * This type is used to simplify code of last_msg_mbox internals.
69  * Instead of writting something like:
70  * \code
71  * template< typename Traits >
72  * class ... {...};
73  *
74  * template< typename Traits, typename Lock_Type >
75  * class ... {...};
76  * \endcode
77  * this config_type allows to write like that:
78  * \code
79  * template< typename Config_Type >
80  * class ... {...};
81  *
82  * template< typename Config_Type >
83  * class ... {...};
84  * \endcode
85  *
86  * \tparam Traits traits type to be used.
87  *
88  * \tparam Lock_Type type of object to be used for thread-safety (like
89  * std::mutex or so_5::null_mutex_t).
90  *
91  * \since
92  * v.1.0.3
93  */
94 template<
95  typename Traits,
96  typename Lock_Type >
98  {
99  using traits_type = Traits;
100  using lock_type = Lock_Type;
101  };
102 
103 /*!
104  * \name Type extractors for config_type
105  * \{
106  */
107 template< typename Config_Type >
108 using traits_t = typename Config_Type::traits_type;
109 
110 template< typename Config_Type >
111 using lock_t = typename Config_Type::lock_type;
112 /*!
113  * \}
114  */
115 
116 //! Helper function for extraction service requests support flag from
117 //! config type.
118 template< typename Config_Type >
121 
122 /*!
123  * \brief An information block about one subscriber.
124  *
125  * \since
126  * v.1.0.3
127  */
129 {
130  /*!
131  * \brief Current status of the subscriber.
132  */
133  enum class state_t
134  {
135  nothing,
137  only_filter,
139  };
140 
141  //! Optional message limit for that subscriber.
143 
144  /*!
145  * \brief Delivery filter for that message for that subscriber.
146  */
148 
149  /*!
150  * \brief Current state of the subscriber parameters.
151  */
153 
154 public :
155  //! Constructor for the case when subscriber info is being
156  //! created during event subscription.
158  const so_5::message_limit::control_block_t * limit )
159  : m_limit( limit )
160  , m_filter( nullptr )
162  {}
163 
164  //! Constructor for the case when subscriber info is being
165  //! created during event subscription.
167  const delivery_filter_t * filter )
168  : m_limit( nullptr )
169  , m_filter( filter )
171  {}
172 
173  bool
174  empty() const
175  {
176  return state_t::nothing == m_state;
177  }
178 
180  limit() const
181  {
182  return m_limit;
183  }
184 
185  //! Set the message limit for the subscriber.
186  /*!
187  * Setting the message limit means that there are subscriptions
188  * for the agent.
189  *
190  * \note The message limit can be nullptr.
191  */
192  void
193  set_limit( const message_limit::control_block_t * limit )
194  {
195  m_limit = limit;
196 
200  }
201 
202  //! Drop the message limit for the subscriber.
203  /*!
204  * Dropping the message limit means that there is no more
205  * subscription for the agent.
206  */
207  void
209  {
210  m_limit = nullptr;
211 
214  }
215 
216  //! Set the delivery filter for the subscriber.
217  void
218  set_filter( const delivery_filter_t & filter )
219  {
220  m_filter = &filter;
221 
225  }
226 
227  //! Drop the delivery filter for the subscriber.
228  void
230  {
231  m_filter = nullptr;
232 
235  }
236 
237  //! Must a message be delivered to the subscriber?
241  message_t & msg ) const
242  {
243  // For the case when there are actual subscriptions.
244  // We assume that will be in 99.9% cases.
245  auto need_deliver = delivery_possibility_t::must_be_delivered;
246 
247  if( state_t::only_filter == m_state )
248  // Only filter, no actual subscriptions.
249  // No message delivery for that case.
250  need_deliver = delivery_possibility_t::no_subscription;
251  else if( state_t::subscriptions_and_filter == m_state )
252  // Delivery must be checked by delivery filter.
253  need_deliver = m_filter->check( subscriber, msg ) ?
254  delivery_possibility_t::must_be_delivered :
255  delivery_possibility_t::disabled_by_delivery_filter;
256 
257  return need_deliver;
258  }
259 };
260 
261 //
262 // messages_table_item_t
263 //
264 /*!
265  * \brief A type of item of message table for retained message mbox.
266  *
267  * For each message type is necessary to store:
268  * - a list of subscriber for that message;
269  * - the last message sent.
270  *
271  * This type is intended to be used as a container for such data.
272  *
273  * \since
274  * v.1.0.3
275  */
277  {
278  //! A special coparator for agents with respect to
279  //! agent's priority.
281  {
282  bool operator()( agent_t * a, agent_t * b ) const
283  {
284  return ::so_5::impl::special_agent_ptr_compare( *a, *b );
285  }
286  };
287 
288  //! Type of subscribers map.
289  using subscribers_map_t =
291 
292  //! Subscribers.
293  /*!
294  * Can be empty. This is for case when the first message was sent
295  * when there is no subscribers yet.
296  */
298 
299  //! Retained message.
300  /*!
301  * Can be nullptr. It means that there is no any attempts to send
302  * a message of this type.
303  */
305  };
306 
307 //
308 // template_independent_mbox_data_t
309 //
310 /*!
311  * \brief A mixin with actual data which is necessary for implementation
312  * of retained mbox.
313  *
314  * This data type doesn't depend on any template parameters.
315  *
316  * \since
317  * v.1.0.3
318  */
320  {
321  //! ID of the mbox.
323 
324  //! Type of messages table.
325  using messages_table_t =
327 
328  //! Table of current subscriptions and messages.
330 
332  };
333 
334 //
335 // detect_invocation_type_for_retained_msg
336 //
337 /*!
338  * \brief Detection of invocation_type for a retained message.
339  *
340  * \since
341  * v.1.2.0
342  */
343 inline invocation_type_t
345  const message_ref_t & msg ) noexcept
346  {
347  invocation_type_t result = invocation_type_t::event;
348  switch( message_kind(msg) )
349  {
350  case message_t::kind_t::signal: /* already detected */ break;
351  case message_t::kind_t::classical_message: /* already detected */ break;
352  case message_t::kind_t::user_type_message: /* already detected */ break;
353  case message_t::kind_t::service_request:
354  result = invocation_type_t::service_request;
355  break;
356 
357  case message_t::kind_t::enveloped_msg:
358  result = invocation_type_t::enveloped_msg;
359  break;
360  }
361 
362  return result;
363  }
364 
365 //
366 // actual_mbox_t
367 //
368 
369 /*!
370  * \brief An actual implementation of retained message mbox.
371  *
372  * \tparam Config type with main definitions for this message box type.
373  *
374  * \tparam Tracing_Base base class with implementation of message
375  * delivery tracing methods.
376  *
377  * \since
378  * v.1.0.3
379  */
380 template<
381  typename Config,
382  typename Tracing_Base >
384  : public abstract_message_box_t
385  , private Tracing_Base
386  {
387  public:
388  /*!
389  * \brief Initializing constructor.
390  *
391  * \tparam Tracing_Args parameters for Tracing_Base constructor
392  * (can be empty list if Tracing_Base have only the default constructor).
393  */
394  template< typename... Tracing_Args >
396  //! ID of this mbox.
397  mbox_id_t id,
398  //! Optional parameters for Tracing_Base's constructor.
399  Tracing_Args &&... args )
401  , m_data{ id }
402  {}
403 
404  virtual mbox_id_t
405  id() const override
406  {
407  return this->m_data.m_id;
408  }
409 
410  virtual void
412  const std::type_index & msg_type,
413  const so_5::message_limit::control_block_t * limit,
414  agent_t * subscriber ) override
415  {
417  msg_type,
418  subscriber,
419  [&] {
420  return subscriber_info_t{ limit };
421  },
422  [&]( subscriber_info_t & info ) {
423  info.set_limit( limit );
424  } );
425  }
426 
427  virtual void
429  const std::type_index & msg_type,
430  agent_t * subscriber ) override
431  {
433  msg_type,
434  subscriber,
435  []( subscriber_info_t & info ) {
436  info.drop_limit();
437  } );
438  }
439 
440  virtual std::string
441  query_name() const override
442  {
444  s << "<mbox:type=RETAINED_MPMC:id=" << this->m_data.m_id << ">";
445 
446  return s.str();
447  }
448 
449  virtual mbox_type_t
450  type() const override
451  {
453  }
454 
455  virtual void
457  const std::type_index & msg_type,
458  const message_ref_t & message,
459  unsigned int overlimit_reaction_deep ) const override
460  {
462  *this, // as Tracing_base
463  *this, // as abstract_message_box_t
464  "deliver_message",
466 
468 
470  tracer,
472  msg_type,
473  message,
475  }
476 
477  virtual void
479  const std::type_index & msg_type,
480  const message_ref_t & message,
481  unsigned int overlimit_reaction_deep ) const override
482  {
485  {
488  std::string( "service request cannot be performed "
489  "on retained_msg mboxes"
490  ", msg_type: " ) + msg_type.name() );
491  }
492  else
493  {
495  *this, // as Tracing_Base
496  *this, // as abstract_message_box_t
497  "deliver_service_request",
498  msg_type,
499  message,
501 
503  tracer,
504  msg_type,
505  message,
507  }
508  }
509 
510  virtual void
512  const std::type_index & msg_type,
513  const message_ref_t & message,
514  unsigned int overlimit_reaction_deep ) override
515  {
517  *this, // as Tracing_base
518  *this, // as abstract_message_box_t
519  "deliver_enveloped_msg",
521 
523 
525  tracer,
527  msg_type,
528  message,
530  }
531 
532  virtual void
534  const std::type_index & msg_type,
535  const delivery_filter_t & filter,
536  agent_t & subscriber ) override
537  {
539  msg_type,
540  &subscriber,
541  [&] {
542  return subscriber_info_t{ &filter };
543  },
544  [&]( subscriber_info_t & info ) {
546  } );
547  }
548 
549  virtual void
551  const std::type_index & msg_type,
552  agent_t & subscriber ) noexcept override
553  {
555  msg_type,
556  &subscriber,
557  []( subscriber_info_t & info ) {
558  info.drop_filter();
559  } );
560  }
561 
562  private :
563  //! Data of this message mbox.
564  /*!
565  * \note
566  * It marked as mutable because it must be modified in
567  * const-methods like do_deliver_message().
568  */
570 
571  //! Object lock.
572  /*!
573  * \note
574  * It marked as mutable because it must be modified in
575  * const-methods like do_deliver_message().
576  */
577  mutable lock_t<Config> m_lock;
578 
579  template< typename Info_Maker, typename Info_Changer >
580  void
582  const std::type_index & msg_type,
583  agent_t * subscriber,
584  Info_Maker maker,
585  Info_Changer changer )
586  {
588 
589  // If there is no item for this message type it will be
590  // created automatically.
591  auto & table_item = this->m_data.m_messages_table[ msg_type ];
592 
595  // There is no subscriber yet. It must be added.
597  subscriber, maker() ).first;
598  else
599  // Subscriber is known. It must be updated.
601 
602  // If there is a retained message then delivery attempt
603  // must be performed.
604  // NOTE: an exception at this stage doesn't remove new subscription.
607  msg_type,
609  *subscriber,
611  }
612 
613  template< typename Info_Changer >
614  void
616  const std::type_index & msg_type,
617  agent_t * subscriber,
618  Info_Changer changer )
619  {
621 
623  if( it_table_item != this->m_data.m_messages_table.end() )
624  {
625  auto & table_item = it_table_item->second;
626 
628  subscriber );
630  {
631  // Subscriber is found and must be modified.
633 
634  // If info about subscriber becomes empty after
635  // modification then subscriber info must be removed.
636  if( it_subscriber->second.empty() )
638  }
639  }
640  }
641 
642  void
644  typename Tracing_Base::deliver_op_tracer const & tracer,
645  invocation_type_t invocation_type,
646  const std::type_index & msg_type,
647  const message_ref_t & message,
648  unsigned int overlimit_reaction_deep ) const
649  {
651 
652  // If there is no item for this message type it will be
653  // created automatically.
654  auto & table_item = this->m_data.m_messages_table[ msg_type ];
655 
656  // Message must be stored as retained.
658 
660  if( !subscribers.empty() )
661  for( const auto & kv : subscribers )
663  *(kv.first),
664  kv.second,
665  tracer,
667  msg_type,
668  message,
670  else
672  }
673 
674  void
676  agent_t & subscriber,
677  const subscriber_info_t & subscriber_info,
678  typename Tracing_Base::deliver_op_tracer const & tracer,
679  invocation_type_t invocation_type,
680  const std::type_index & msg_type,
681  const message_ref_t & message,
682  unsigned int overlimit_reaction_deep ) const
683  {
684  const auto delivery_status =
686  subscriber,
687  *(message.get()) );
688 
690  {
691  using namespace so_5::message_limit::impl;
692 
694  this->m_data.m_id,
696  subscriber,
698  msg_type,
699  message,
702  [&] {
704 
706  subscriber,
708  this->m_data.m_id,
709  msg_type,
710  message );
711  } );
712  }
713  else
716  }
717 
718  void
720  typename Tracing_Base::deliver_op_tracer const & tracer,
721  const std::type_index & msg_type,
722  const message_ref_t & message,
723  unsigned int overlimit_reaction_deep ) const
724  {
725  using namespace so_5::message_limit::impl;
726 
728  [&] {
730 
731  auto it_msg = this->m_data.m_messages_table.find( msg_type );
732  if( it_msg == this->m_data.m_messages_table.end() )
733  {
735 
738  std::string(
739  "no service handlers (no subscribers "
740  "for message), msg_type: " )
741  + msg_type.name() );
742  }
743 
745  if( 0 == subscribers.size() )
746  {
748 
751  std::string(
752  "no service handlers (no subscribers "
753  "for message), msg_type: " )
754  + msg_type.name() );
755  }
756  else if( 1 != subscribers.size() )
759  std::string(
760  "more than one service handler found"
761  ", msg_type: " ) + msg_type.name() );
762 
763  // Key is subscriber pointer,
764  // value is a subscriber_info_t.
765  auto & kv = *(subscribers.begin());
767  *(kv.first),
768  kv.second,
769  tracer,
770  msg_type,
771  message,
773  } );
774  }
775 
776  void
778  agent_t & subscriber,
779  const subscriber_info_t & subscriber_info,
780  typename Tracing_Base::deliver_op_tracer const & tracer,
781  const std::type_index & msg_type,
782  const message_ref_t & message,
783  unsigned int overlimit_reaction_deep ) const
784  {
785  auto & svc_request_param =
786  dynamic_cast< msg_service_request_base_t & >( *message )
787  .query_param();
788 
789  const auto delivery_status =
791  subscriber,
793 
795  {
796  using namespace so_5::message_limit::impl;
797 
799  this->m_data.m_id,
801  subscriber,
803  msg_type,
804  message,
807  [&] {
809 
811  subscriber,
813  this->m_data.m_id,
814  msg_type,
815  message );
816  } );
817  }
818  else
819  {
822  delivery_status );
823 
826  std::string( "no service handlers (no subscribers "
827  "for message or subscriber is blocked by "
828  "delivery filter), msg_type: " )
829  + msg_type.name() );
830  }
831  }
832 
833  /*!
834  * \brief An attempt to deliver retained message to the new subscriber.
835  *
836  * This attempt will be performed only if there is the retained message.
837  */
838  void
840  const std::type_index & msg_type,
841  const message_ref_t & retained_msg,
842  agent_t & subscriber,
843  const subscriber_info_t & subscriber_info )
844  {
845  if( retained_msg )
846  {
847  const unsigned int overlimit_reaction_deep = 0;
848 
850  *this, // as Tracing_base
851  *this, // as abstract_message_box_t
852  "deliver_message_on_subscription",
853  msg_type,
854  retained_msg,
856 
858  subscriber,
860  tracer,
862  msg_type,
863  retained_msg,
865  }
866  }
867 
868  /*!
869  * \brief Ensures that message is an immutable message.
870  *
871  * Checks mutability flag and throws an exception if message is
872  * a mutable one.
873  */
874  void
876  const std::type_index & msg_type,
877  const message_ref_t & what ) const
878  {
883  "an attempt to deliver mutable message via MPMC mbox"
884  ", msg_type=" + std::string(msg_type.name()) );
885  }
886  };
887 
888 } /* namespace details */
889 
890 //
891 // no_service_request_traits_t
892 //
893 /*!
894  * \brief Traits for the case when service requests are not supported.
895  *
896  * \since
897  * v.1.0.3
898  */
900  {
903  };
904 
905 //
906 // with_service_request_traits_t
907 //
908 /*!
909  * \brief Traits for the case when service requests are supported.
910  *
911  * Service requests are now supported on retained message mboxes by
912  * default. This traits class can be use to enable them:
913  * \code
914  * const so_5::mbox_t retained_mbox =
915  * so_5::extra::mboxes::retained_msg::make_mbox<
916  * so_5::extra::mboxes::retained_msg::with_service_request_traits_t>(env);
917  * \endcode
918  *
919  * \since
920  * v.1.0.3
921  */
923  {
926  };
927 
928 //
929 // default_traits_t
930 //
931 /*!
932  * \brief Default traits for retained message mbox.
933  */
934 using default_traits_t = no_service_request_traits_t;
935 
936 //
937 // make_mbox
938 //
939 /*!
940  * \brief Create an instance of retained message mbox.
941  *
942  * Simple usage example:
943  * \code
944  * so_5::environment_t & env = ...;
945  * const so_5::mbox_t retained_mbox = so_5::extra::mboxes::retained_msg::make_mbox<>(env);
946  * so_5::send<Some_Message>(retained_mbox, ...);
947  * \endcode
948  * An instance of default implementation retained message mbox will be created.
949  * This instance will be protected by std::mutex.
950  *
951  * If you want to use retained_mbox in a single-threaded environment
952  * without a multithreaded protection then so_5::null_mutex_t (or any
953  * similar null-mutex implementation) can be used:
954  * \code
955  * so_5::environment_t & env = ...
956  * const so_5::mbox_t retained_mbox =
957  * so_5::extra::mboxes::retained_msg::make_mbox<
958  * so_5::extra::mboxes::retained_msg::default_traits_t,
959  * so_5::null_mutex_t>(env);
960  * so_5::send<Some_Message>(retained_mbox, ...);
961  * \endcode
962  *
963  * If you want to use your own mutex-like object (with interface which
964  * allows to use your mutex-like class with std::lock_guard) then you can
965  * do it similar way:
966  * \code
967  * so_5::environment_t & env = ...
968  * const so_5::mbox_t retained_mbox =
969  * so_5::extra::mboxes::retained_msg::make_mbox<
970  * so_5::extra::mboxes::retained_msg::default_traits_t,
971  * Your_Own_Mutex_Class>(env);
972  * so_5::send<Some_Message>(retained_mbox, ...);
973  * \endcode
974  *
975  * By default service requests are not supported on retained message mboxes.
976  * It means that attempt to call `so_5::request_future` or
977  * `so_5::request_value` on retained message mbox will fail. To enable
978  * service requests it is necessary to specify appropriate traits type.
979  * This traits type must contains constexpr static member of
980  * type service_request_support_t with name service_request_support.
981  * For example:
982  * \code
983  * struct my_retained_msg_traits {
984  * static constexpr so_5::extra::mboxes::retained_msg::service_request_support_t
985  * service_request_support =
986  * so_5::extra::mboxes::retained_msg::service_request_support_t::enabled;
987  * ...
988  * };
989  * ...
990  * const so_5::mbox_t retained_mbox =
991  * so_5::extra::mboxes::retained_msg::make_mbox<
992  * my_retained_msg_traits>(env);
993  * \endcode
994  * NOTE. Class with_service_request_traits_t can be used for that purpose:
995  * \code
996  * const so_5::mbox_t retained_mbox =
997  * so_5::extra::mboxes::retained_msg::make_mbox<
998  * so_5::extra::mboxes::retained_msg::with_service_request_traits_t>(env);
999  * \endcode
1000  *
1001  * \tparam Traits type with traits of mbox implementation.
1002  *
1003  * \tparam Lock_Type a type of mutex to be used for protection of
1004  * retained message mbox content. This must be a DefaultConstructible
1005  * type with interface which allows to use Lock_Type with std::lock_guard.
1006  *
1007  * \since
1008  * v.1.0.3
1009  */
1010 template<
1011  typename Traits = default_traits_t,
1012  typename Lock_Type = std::mutex >
1013 mbox_t
1015  {
1017 
1018  return env.make_custom_mbox(
1019  []( const mbox_creation_data_t & data )
1020  {
1021  mbox_t result;
1022 
1024  {
1025  using T = details::actual_mbox_t<
1026  config_type,
1028 
1029  result = mbox_t{ new T{ data.m_id, data.m_tracer.get() } };
1030  }
1031  else
1032  {
1033  using T = details::actual_mbox_t<
1034  config_type,
1036  result = mbox_t{ new T{ data.m_id } };
1037  }
1038 
1039  return result;
1040  } );
1041  }
1042 
1043 } /* namespace retained_msg */
1044 
1045 } /* namespace mboxes */
1046 
1047 } /* namespace extra */
1048 
1049 } /* namespace so_5 */
constexpr service_request_support_t service_request_support_v
Helper function for extraction service requests support flag from config type.
void modify_and_remove_subscriber_if_needed(const std::type_index &msg_type, agent_t *subscriber, Info_Changer changer)
A type of item of message table for retained message mbox.
mbox_t make_mbox(environment_t &env)
Create an instance of retained message mbox.
void try_deliver_retained_message_to(const std::type_index &msg_type, const message_ref_t &retained_msg, agent_t &subscriber, const subscriber_info_t &subscriber_info)
An attempt to deliver retained message to the new subscriber.
subscriber_info_t(const delivery_filter_t *filter)
Constructor for the case when subscriber info is being created during event subscription.
Traits for the case when service requests are supported.
virtual void do_deliver_enveloped_msg(const std::type_index &msg_type, const message_ref_t &message, unsigned int overlimit_reaction_deep) override
template_independent_mbox_data_t m_data
Data of this message mbox.
virtual void do_deliver_message(const std::type_index &msg_type, const message_ref_t &message, unsigned int overlimit_reaction_deep) const override
static constexpr service_request_support_t service_request_support
void do_deliver_service_request_impl(typename Tracing_Base::deliver_op_tracer const &tracer, const std::type_index &msg_type, const message_ref_t &message, unsigned int overlimit_reaction_deep) const
void do_deliver_message_impl(typename Tracing_Base::deliver_op_tracer const &tracer, invocation_type_t invocation_type, const std::type_index &msg_type, const message_ref_t &message, unsigned int overlimit_reaction_deep) const
Traits for the case when service requests are not supported.
Ranges for error codes of each submodules.
Definition: details.hpp:14
static constexpr service_request_support_t service_request_support
service_request_support_t
Indiction of service requests support for retained message mbox.
A mixin with actual data which is necessary for implementation of retained mbox.
messages_table_t m_messages_table
Table of current subscriptions and messages.
An actual implementation of retained message mbox.
A special coparator for agents with respect to agent&#39;s priority.
virtual void set_delivery_filter(const std::type_index &msg_type, const delivery_filter_t &filter, agent_t &subscriber) override
invocation_type_t detect_invocation_type_for_retained_msg(const message_ref_t &msg) noexcept
Detection of invocation_type for a retained message.
Service requests are not supported. This the default value for retained message mboxes.
const so_5::message_limit::control_block_t * m_limit
Optional message limit for that subscriber.
void do_deliver_service_request_to_subscriber(agent_t &subscriber, const subscriber_info_t &subscriber_info, typename Tracing_Base::deliver_op_tracer const &tracer, const std::type_index &msg_type, const message_ref_t &message, unsigned int overlimit_reaction_deep) const
void drop_limit()
Drop the message limit for the subscriber.
A helper type which is a collection of type parameters.
void set_limit(const message_limit::control_block_t *limit)
Set the message limit for the subscriber.
state_t m_state
Current state of the subscriber parameters.
void ensure_immutable_message(const std::type_index &msg_type, const message_ref_t &what) const
Ensures that message is an immutable message.
virtual void subscribe_event_handler(const std::type_index &msg_type, const so_5::message_limit::control_block_t *limit, agent_t *subscriber) override
void do_deliver_message_to_subscriber(agent_t &subscriber, const subscriber_info_t &subscriber_info, typename Tracing_Base::deliver_op_tracer const &tracer, invocation_type_t invocation_type, const std::type_index &msg_type, const message_ref_t &message, unsigned int overlimit_reaction_deep) const
void set_filter(const delivery_filter_t &filter)
Set the delivery filter for the subscriber.
An information block about one subscriber.
virtual void drop_delivery_filter(const std::type_index &msg_type, agent_t &subscriber) noexcept override
const delivery_filter_t * m_filter
Delivery filter for that message for that subscriber.
delivery_possibility_t must_be_delivered(agent_t &subscriber, message_t &msg) const
Must a message be delivered to the subscriber?
void drop_filter()
Drop the delivery filter for the subscriber.
const message_limit::control_block_t * limit() const
virtual void do_deliver_service_request(const std::type_index &msg_type, const message_ref_t &message, unsigned int overlimit_reaction_deep) const override
actual_mbox_t(mbox_id_t id, Tracing_Args &&... args)
Initializing constructor.
const int rc_service_request_via_retained_msg_mbox
An attempt perform service request via retained message mbox.
virtual void unsubscribe_event_handlers(const std::type_index &msg_type, agent_t *subscriber) override
void insert_or_modify_subscriber(const std::type_index &msg_type, agent_t *subscriber, Info_Maker maker, Info_Changer changer)