SObjectizer-5 Extra
shutdowner.hpp
Go to the documentation of this file.
1 /*!
2  * \file
3  * \brief Implementation of shutdowner-related stuff.
4  */
5 
6 #pragma once
7 
8 #include <so_5_extra/error_ranges.hpp>
9 
10 #include <so_5/rt/impl/h/msg_tracing_helpers.hpp>
11 #include <so_5/rt/impl/h/message_limit_internals.hpp>
12 #include <so_5/rt/impl/h/agent_ptr_compare.hpp>
13 
14 #include <so_5/details/h/sync_helpers.hpp>
15 
16 #include <so_5/rt/h/mbox.hpp>
17 #include <so_5/rt/h/send_functions.hpp>
18 
19 #include <so_5/h/outliving.hpp>
20 
21 namespace so_5 {
22 
23 namespace extra {
24 
25 namespace shutdowner {
26 
27 namespace errors {
28 
29 /*!
30  * \brief An attempt to use illegal message type.
31  *
32  * For example: shutdowner mbox allows subscription only to
33  * shutdown_initiated message.
34  */
37 
38 /*!
39  * \brief Subscription to shutdowner mbox when shutdown in progess
40  * is prohibited.
41  */
44 
45 } /* namespace errors */
46 
47 /*!
48  * \brief A message to be used to inform about start of shutdown operation.
49  *
50  * \note
51  * This is a message, not a signal. This message is empty now but it
52  * can be extended in future versions of so_5_extra.
53  */
54 struct shutdown_initiated_t : public so_5::message_t {};
55 
56 namespace details {
57 
58 /*!
59  * \brief Implementation of stop_guard for shutdowner's purposes.
60  *
61  * This implementation sends shutdown_initiated_t message to the specified
62  * mbox.
63  */
65  {
66  //! Mbox to which shutdown_initiated must be sent.
68 
69  public :
70  //! Initializing constructor.
71  shutdowner_guard_t( so_5::mbox_t notify_mbox )
73  {}
74 
75  virtual void
76  stop() noexcept override
77  {
78  so_5::send< shutdown_initiated_t >( m_notify_mbox );
79  }
80  };
81 
82 /*!
83  * \brief A signal which is used to limit time of shutdown operation.
84  */
85 struct shutdown_time_elapsed_t final : public so_5::message_t {};
86 
87 /*!
88  * \brief Special mbox to receive and handle a signal about time limit.
89  *
90  * This mbox implements just one method: do_deliver_message(). A std::abort()
91  * is called in this method if shutdown operation is not finished yet.
92  */
94  : public abstract_message_box_t
95  {
96  public :
97  //! Initializing constructor.
99  //! SObjectizer environment to work in.
100  //! It is necessary to access error_logging before calling std::abort().
101  outliving_reference_t< environment_t > env,
102  //! Unique ID of this mbox.
103  mbox_id_t id )
104  : m_env( env )
105  , m_id( id )
106  {}
107 
108  virtual mbox_id_t
109  id() const override
110  {
111  return m_id;
112  }
113 
114  virtual void
116  const std::type_index & /*type_index*/,
117  const message_limit::control_block_t * /*limit*/,
118  agent_t * /*subscriber*/ ) override
119  {
120  SO_5_THROW_EXCEPTION( rc_not_implemented,
121  "subscribe_event_handler is not implemented for "
122  "time_elapsed_mbox" );
123  }
124 
125  virtual void
127  const std::type_index & /*type_index*/,
128  agent_t * /*subscriber*/ ) override
129  {
130  SO_5_THROW_EXCEPTION( rc_not_implemented,
131  "subscribe_event_handler is not implemented for "
132  "time_elapsed_mbox" );
133  }
134 
135  virtual std::string
136  query_name() const override
137  {
138  std::ostringstream ss;
139  ss << "<mbox:type=MPSC:shutdowner_time_elapsed:id=" << m_id << ">";
140  return ss.str();
141  }
142 
143  virtual mbox_type_t
144  type() const override
145  {
146  return mbox_type_t::multi_producer_single_consumer;
147  }
148 
149  virtual void
151  const std::type_index & /*msg_type*/,
152  const message_ref_t & /*message*/,
153  unsigned int /*overlimit_reaction_deep*/ ) const override
154  {
155  m_env.get().error_logger().log(
156  __FILE__, __LINE__,
157  "Time of shutdown operation is elapsed. "
158  "Application will be terminated." );
159  std::abort();
160  }
161 
162  virtual void
164  const std::type_index & /*msg_type*/,
165  const message_ref_t & /*message*/,
166  unsigned int /*overlimit_reaction_deep*/ ) const override
167  {
168  SO_5_THROW_EXCEPTION( rc_not_implemented,
169  "do_deliver_service_request is not implemented for "
170  "time_elapsed_mbox" );
171  }
172 
173  virtual void
175  const std::type_index & /*msg_type*/,
176  const delivery_filter_t & /*filter*/,
177  agent_t & /*subscriber*/ ) override
178  {
179  SO_5_THROW_EXCEPTION( rc_not_implemented,
180  "set_delivery_filter is not implemented for "
181  "time_elapsed_mbox" );
182  }
183 
184  virtual void
186  const std::type_index & /*msg_type*/,
187  agent_t & /*subscriber*/ ) noexcept override
188  {
189  /* Nothing to do. */
190  }
191 
192  private :
193  //! SOEnv to work in.
195  //! Unique ID of that mbox.
197  };
198 
199 //
200 // subscriber_info_t
201 //
202 /*!
203  * \brief Description of one subscriber.
204  */
206  {
207  //! Actual subscriber.
208  /*!
209  * Can't be nullptr.
210  */
212  //! Message limit for that subscriber.
213  /*!
214  * Can be nullptr if message limit is not used.
215  */
217 
218  //! Initializing constructor.
220  agent_t * subscriber,
221  const message_limit::control_block_t * limits )
223  , m_limits(limits)
224  {}
225 
226  //! Comparison operator.
227  /*!
228  * Compares only pointers to m_subscriber with respects
229  * to agent's priority.
230  */
231  bool
232  operator<( const subscriber_info_t & o ) const
233  {
234  return ::so_5::impl::special_agent_ptr_compare(
235  *m_subscriber, *(o.m_subscriber) );
236  }
237  };
238 
239 //
240 // subscriber_container_t
241 //
242 /*!
243  * \brief Type of subscriber's container.
244  */
246 
247 namespace status {
248 
249 //! Avaliable statuses of shutdown operation.
250 enum class value_t
251  {
252  //! Shutdown is not started yet.
253  not_started,
254  //! Shutdown is started but there are some pending subscribers.
255  started,
256  //! All subscribers are unsubscribed.
257  //! Shutdown can and should be completed.
259  };
260 
264 
265 //! Which action must be performed after updating status of shutdown operation.
267  {
268  //! No action is required.
269  do_nothing,
270  //! Shutdown action must be completed.
272  };
273 
274 //! Special object which holds status.
275 /*!
276  * Updates for the status are enabled only to instances of updater_t class.
277  */
278 class holder_t
279  {
280  friend class updater_t;
281 
283 
284  public :
285  value_t
286  current() const { return m_status; }
287  };
288 
289 //! Special object to change the status and detect deferred action to be performed.
291  {
294 
295  public :
297  outliving_reference_t< holder_t > status )
298  : m_status( status )
299  {}
300 
301  value_t
302  current() const { return m_status.get().current(); }
303 
304  void
305  update( value_t new_status )
306  {
307  m_status.get().m_status = new_status;
308  if( value_t::must_be_completed == new_status )
310  else
312  }
313 
315  action() const { return m_action; }
316  };
317 
318 } /* namespace status */
319 
320 //
321 // notify_mbox_data_t
322 //
323 /*!
324  * \brief An internal data of notify_mbox.
325  *
326  * It is collected in separate struct to provide ability to mark
327  * object of that struct as mutable. It is necessary because some
328  * of abstract_message_box_t's methods are declared as const by
329  * historical reasons.
330  */
332 {
333  //! Status of the shutdown operation.
335 
336  //! List of actual subscribers.
338 
339  //! Mbox to be used for delayed shutdown_time_elapsed message.
341  //! A time for shutdown operation.
343 
344  //! Timer ID for shutdown_time_elapsed message.
345  /*!
346  * Will be used for canceling of delayed message when shutdown is
347  * completed.
348  *
349  * Will receive actual value only when shutdown operation started.
350  */
352 
353  //! Initializing constructor.
355  mbox_t time_elapsed_mbox,
356  std::chrono::steady_clock::duration max_shutdown_time )
359  {}
360 };
361 
362 //
363 // notify_mbox_t
364 //
365 /*!
366  * \brief A special mbox which must be used for notification about
367  * shutdown operation.
368  *
369  * \tparam Lock_Type type of lock to be used for thread safety
370  * \tparam Tracing_Base type that implements message tracing stuff
371  * It is expected to be so_5::impl::msg_tracing_helpers::tracing_enabled_base
372  * or so_5::impl::msg_tracing_helpers::tracing_disabled_base
373  */
374 template< typename Lock_Type, typename Tracing_Base >
376  : public abstract_message_box_t
378  , private Tracing_Base
379  {
380  public :
381  template< typename... Tracing_Base_Args >
383  //! SObjectizer Environment to work in.
384  outliving_reference_t< environment_t > env,
385  //! A mbox for delayed message shutdown_time_elapsed_t.
386  mbox_t time_elapsed_mbox,
387  //! Time for the whole shutdown operation.
388  std::chrono::steady_clock::duration max_shutdown_time,
389  //! Unique ID of that mbox.
390  mbox_id_t id,
391  //! Params for tracing stuff.
392  Tracing_Base_Args && ...tracing_args )
394  , m_env( env )
395  , m_id( id )
397  {
398  // Now we can create and install shutdowner_guard to
399  // prevent SObjectizer from shutdown.
400  auto guard = std::make_shared< shutdowner_guard_t >( mbox_t(this) );
403  }
404 
405  virtual mbox_id_t
406  id() const override
407  {
408  return m_id;
409  }
410 
411  virtual void
413  const std::type_index & type_index,
414  const message_limit::control_block_t * limit,
415  agent_t * subscriber ) override
416  {
418  this->lock_and_perform( [&] {
420  } );
421  }
422 
423  virtual void
425  const std::type_index & type_index,
426  agent_t * subscriber ) override
427  {
429  const auto action = this->lock_and_perform( [&] {
431  } );
432 
435  }
436 
437  virtual std::string
438  query_name() const override
439  {
441  ss << "<mbox:type=MPMC:shutdowner:id=" << m_id << ">";
442  return ss.str();
443  }
444 
445  virtual mbox_type_t
446  type() const override
447  {
449  }
450 
451  virtual void
453  const std::type_index & msg_type,
454  const message_ref_t & message,
455  unsigned int /*overlimit_reaction_deep*/ ) const override
456  {
458  const auto action = do_initiate_shutdown( msg_type, message );
461  }
462 
463  virtual void
465  const std::type_index & msg_type,
466  const message_ref_t & /*message*/,
467  unsigned int /*overlimit_reaction_deep*/ ) const override
468  {
471  "do_deliver_service_request is not implemented for "
472  "shutdowner mbox" );
473  }
474 
475  virtual void
477  const std::type_index & msg_type,
478  const delivery_filter_t & /*filter*/,
479  agent_t & /*subscriber*/ ) override
480  {
483  "unable to set delivery filter to shutdowner mbox" );
484  }
485 
486  virtual void
488  const std::type_index & /*msg_type*/,
489  agent_t & /*subscriber*/ ) noexcept override
490  {
491  /* Nothing to do. */
492  }
493 
494  private :
495  //! SObjectizer Environment to work in.
497 
498  //! Stop_guard which prevents SObjectizer from shutdown.
500 
501  //! Unique ID of that mbox.
503 
504  //! Actual mbox data.
505  /*!
506  * \attention
507  * It is marked as `mutable` because some methods of
508  * abstract_message_box_t are const by historical reasons.
509  * But there is a necessity to change mbox's data inside such methods.
510  */
512 
513  //! Check for valid type of message to be handled.
514  /*!
515  * \note
516  * Only shutdown_initiated_t message can be handled by that mbox type.
517  */
518  static void
519  ensure_valid_message_type( const std::type_index & type_index )
520  {
521  if( type_index != typeid(shutdown_initiated_t) )
524  "only shutdown_initiated_t message type is allowed to "
525  "be used with shutdowner mbox" );
526  }
527 
528  //! Main subscription actions.
529  /*!
530  * May throw if shutdown is in progress or already completed.
531  */
532  void
534  const message_limit::control_block_t * limit,
535  agent_t * subscriber )
536  {
540  "a creation of new subscription is disabled during "
541  "shutdown procedure" );
542 
544  auto it = std::lower_bound(
547  info );
549  }
550 
551  //! Main unsubscription actions.
552  /*!
553  * Returns the action to be performed (shutdown completion may be
554  * necessary).
555  */
557  do_event_unsubscripton( agent_t * subscriber )
558  {
561 
562  subscriber_info_t info{ subscriber, nullptr };
563  auto it = std::lower_bound(
566  info );
567  if( it != std::end(m_data.m_subscribers) &&
569  {
571 
573  {
574  if( m_data.m_subscribers.empty() )
575  {
578  }
579  }
580  }
581 
582  return status_updater.action();
583  }
584 
585  //! Do all necessary actions for completion of shutdown.
586  /*!
587  * \note
588  * This method is marked as const because is may be called from
589  * const virtual methods.
590  */
591  void
593  {
595 
597  }
598 
599  //! Do all necessary actions for start of shutdown operation.
600  /*!
601  * Returns the action to be performed (shutdown completion may be
602  * necessary).
603  *
604  * \note
605  * This method is marked as const because is may be called from
606  * const virtual methods.
607  */
610  const std::type_index & msg_type,
611  const message_ref_t & message ) const
612  {
615 
616  if( status::not_started == updater.current() )
617  {
619  if( !m_data.m_subscribers.empty() )
620  {
623  }
624  else
625  {
627  }
628  }
629 
630  return updater.action();
631  }
632 
633  //! Send shutdown_initiated message to all actual subscribers.
634  /*!
635  * \note
636  * This method is marked as const because is may be called from
637  * const virtual methods.
638  */
639  void
641  const std::type_index & msg_type,
642  const message_ref_t & message ) const
643  {
644  constexpr unsigned int overlimit_reaction_deep = 0u;
645 
647  *this, // as Tracing_Base
648  *this, // as abstract_message_box_t
649  "deliver_message",
651 
652  for( const auto & subscriber : m_data.m_subscribers )
653  {
654  using namespace so_5::message_limit::impl;
655 
657  m_id,
661  msg_type,
662  message,
665  [&] {
667 
671  m_id,
672  msg_type,
673  message );
674  } );
675  }
676  }
677 
678  //! Initiate delayed shutdown_time_elapsed message.
679  /*!
680  * \note
681  * This method is marked as const because is may be called from
682  * const virtual methods.
683  */
684  void
686  {
688  m_env,
691  std::chrono::milliseconds::zero() );
692  }
693  };
694 
695 } /* namespace details */
696 
697 //
698 // layer_t
699 //
700 /*!
701  * \brief An interface of shutdowner layer.
702  *
703  * This is a public interface of actual layer. An user should use only
704  * that interface when it want to work with shutdown layer.
705  *
706  * For example, to subscribe to shutdown_initiated_t message it is neccessary
707  * to receive a pointer/reference to layer_t and call notify_mbox() method:
708  * \code
709  * // To make a subscription to shutdown notification.
710  * class my_agent final : public so_5::agent_t {
711  * public :
712  * my_agent(context_t ctx) : so_5::agent_t(std::move(ctx)) {
713  * // Long way:
714  * so_5::extra::shutdowner::layer_t * s =
715  * so_environment().query_layer<so_5::extra::shutdowner::layer_t>();
716  * so_subscribe(s->notify_mbox()).event(&my_agent::on_shutdown);
717  *
718  * // Shortest way:
719  * so_subscribe(so_5::extra::shutdowner::layer(so_environment()).notify_mbox())
720  * .event(&my_agent::on_shutdown);
721  * ...
722  * }
723  * ...
724  * private :
725  * void on_shutdown(mhood_t<so_5::extra::shutdowner::shutdown_initiated_t>)
726  * {...}
727  * };
728  * \endcode
729  *
730  * To initiate shutdown it is necessary to call so_5::environment_t::stop()
731  * method:
732  * \code
733  * so_environment().stop();
734  * \endcode
735  */
736 class layer_t : public ::so_5::layer_t
737  {
738  public :
739  //! Get a mbox which can be used for subscription to
740  //! shutdown_initiated message.
741  virtual mbox_t
742  notify_mbox() const = 0;
743  };
744 
745 namespace details {
746 
747 //
748 // layer_template_t
749 //
750 /*!
751  * \brief A template-based implementation of shutdowner layer.
752  *
753  * \note
754  * It creates all shutdowner-related stuff in start() method.
755  */
756 template< typename Lock_Type >
758  {
759  public :
760  //! Initializing constructor.
762  //! Maximum time for the shutdown operation.
763  std::chrono::steady_clock::duration shutdown_time )
765  {}
766 
767  virtual mbox_t
768  notify_mbox() const override
769  {
770  return m_notify_mbox;
771  }
772 
773  virtual void
774  start() override
775  {
777  [&]( const mbox_creation_data_t & data ) {
779  } );
780 
782  [&]( const mbox_creation_data_t & data ) {
784  data,
785  std::move( time_elapsed_mbox ) );
786  } );
787  }
788 
789  private :
790  //! Maximum time for the shutdown operation.
792 
793  //! Notification mbox.
794  /*!
795  * Will be created in start() method. Until then it is a null pointer.
796  */
798 
799  //! Create mbox for delayed shutdown_time_elapsed message.
800  mbox_t
802  //! Parameters for the new mbox.
803  const mbox_creation_data_t & data )
804  {
805  return mbox_t( new details::time_elapsed_mbox_t(
807  data.m_id ) );
808  }
809 
810  //! Create notification mbox.
811  /*!
812  * A new mbox will be created with respect to message tracing stuff.
813  */
814  mbox_t
816  //! Parameters for the new mbox.
817  const mbox_creation_data_t & data,
818  //! A mbox to be used for delayed shutdown_time_elapsed message.
820  {
821  mbox_t result;
822 
824  {
825  using T = details::notify_mbox_t<
826  Lock_Type,
828  result = mbox_t( new T(
832  data.m_id,
833  data.m_tracer.get() ) );
834  }
835  else
836  {
837  using T = details::notify_mbox_t<
838  Lock_Type,
840  result = mbox_t( new T(
844  data.m_id ) );
845  }
846 
847  return result;
848  }
849  };
850 
851 } /* namespace details */
852 
853 //
854 // make_layer
855 //
856 /*!
857  * \brief Main function to create an instance of shutdowner layer.
858  *
859  * Usage example:
860  * \code
861  * // Creation of layer with default mutex type.
862  * so_5::launch([](so_5::environment_t & env) {...},
863  * [](so_5::environment_params_t & params) {
864  * params.add_layer( so_5::extra::shutdowner::make_layer<>(30s) );
865  * });
866  *
867  * // Creation of layer with user-provided spinlock type.
868  * so_5::launch([](so_5::environment_t & env) {...},
869  * [](so_5::environment_params_t & params) {
870  * params.add_layer( so_5::extra::shutdowner::make_layer<my_spinlock_t>(30s));
871  * });
872  *
873  * // Creation of layer with null_mutex.
874  * // Note: null_mutex must be used only for non thread-safe environments.
875  * so_5::launch([](so_5::environment_t & env) {...},
876  * [](so_5::environment_params_t & params) {
877  * // Use single-threaded and not thread-safe environment.
878  * params.infrastructure_factory(
879  * so_5::env_infrastructures::simple_not_mtsafe::factory());
880  * // Shutdowner layer with null_mutex can be used in that environment.
881  * params.add_layer( so_5::extra::shutdowner::make_layer<so_5::null_mutex_t>(30s));
882  * });
883  * \endcode
884  *
885  * \tparam Lock_Type type of lock to be used for thread safety.
886  */
887 template< typename Lock_Type = std::mutex >
890  //! A maximum time for timeout operation.
892  {
895  shutdown_max_time ) );
896 
897  return result;
898  }
899 
900 //
901 // layer
902 //
903 /*!
904  * \brief A helper function to receive a reference to shutdowner layer.
905  *
906  * Usage example:
907  * \code
908  * // To make a subscription to shutdown notification.
909  * class my_agent final : public so_5::agent_t {
910  * public :
911  * my_agent(context_t ctx) : so_5::agent_t(std::move(ctx)) {
912  * auto & s = so_5::extra::shutdowner::layer( so_environment() );
913  * so_subscribe( s.notify_mbox() ).event( &my_agent::on_shutdown );
914  * ...
915  * }
916  * ...
917  * private :
918  * void on_shutdown(mhood_t<so_5::extra::shutdowner::shutdown_initiated_t>)
919  * {...}
920  * };
921  *
922  * // To initiate shutdown.
923  * so_5::extra::shutdowner::layer(env).initiate_shutdown();
924  * \endcode
925  *
926  * \note May throw an exception if shutdowner layer is not defined.
927  */
928 inline ::so_5::extra::shutdowner::layer_t &
929 layer( ::so_5::environment_t & env )
930  {
931  return *(env.query_layer< ::so_5::extra::shutdowner::layer_t >());
932  }
933 
934 } /* namespace shutdowner */
935 
936 } /* namespace extra */
937 
938 } /* namespace so_5 */
virtual std::string query_name() const override
Definition: shutdowner.hpp:136
const so_5::mbox_t m_notify_mbox
Mbox to which shutdown_initiated must be sent.
Definition: shutdowner.hpp:67
const message_limit::control_block_t * m_limits
Message limit for that subscriber.
Definition: shutdowner.hpp:216
An interface of shutdowner layer.
Definition: shutdowner.hpp:736
A message to be used to inform about start of shutdown operation.
Definition: shutdowner.hpp:54
virtual mbox_t notify_mbox() const override
Get a mbox which can be used for subscription to shutdown_initiated message.
Definition: shutdowner.hpp:768
virtual mbox_id_t id() const override
Definition: shutdowner.hpp:406
subscriber_container_t m_subscribers
List of actual subscribers.
Definition: shutdowner.hpp:337
status::holder_t m_status
Status of the shutdown operation.
Definition: shutdowner.hpp:334
Implementation of stop_guard for shutdowner&#39;s purposes.
Definition: shutdowner.hpp:64
virtual void unsubscribe_event_handlers(const std::type_index &type_index, agent_t *subscriber) override
Definition: shutdowner.hpp:424
stop_guard_shptr_t m_shutdowner_guard
Stop_guard which prevents SObjectizer from shutdown.
Definition: shutdowner.hpp:499
void complete_shutdown() const
Do all necessary actions for completion of shutdown.
Definition: shutdowner.hpp:592
const mbox_id_t m_id
Unique ID of that mbox.
Definition: shutdowner.hpp:196
virtual mbox_type_t type() const override
Definition: shutdowner.hpp:144
mbox_t do_make_time_elapsed_mbox(const mbox_creation_data_t &data)
Create mbox for delayed shutdown_time_elapsed message.
Definition: shutdowner.hpp:801
const std::chrono::steady_clock::duration m_max_shutdown_time
A time for shutdown operation.
Definition: shutdowner.hpp:342
outliving_reference_t< environment_t > m_env
SOEnv to work in.
Definition: shutdowner.hpp:194
updater_t(outliving_reference_t< holder_t > status)
Definition: shutdowner.hpp:296
Special object which holds status.
Definition: shutdowner.hpp:278
notify_mbox_data_t m_data
Actual mbox data.
Definition: shutdowner.hpp:511
std::unique_ptr< ::so_5::extra::shutdowner::layer_t > make_layer(std::chrono::steady_clock::duration shutdown_max_time)
Main function to create an instance of shutdowner layer.
Definition: shutdowner.hpp:889
Ranges for error codes of each submodules.
Definition: details.hpp:14
A template-based implementation of shutdowner layer.
Definition: shutdowner.hpp:757
virtual void subscribe_event_handler(const std::type_index &, const message_limit::control_block_t *, agent_t *) override
Definition: shutdowner.hpp:115
mbox_t do_make_notification_mbox(const mbox_creation_data_t &data, mbox_t time_elapsed_mbox)
Create notification mbox.
Definition: shutdowner.hpp:815
virtual void set_delivery_filter(const std::type_index &msg_type, const delivery_filter_t &, agent_t &) override
Definition: shutdowner.hpp:476
bool operator<(const subscriber_info_t &o) const
Comparison operator.
Definition: shutdowner.hpp:232
const std::chrono::steady_clock::duration m_shutdown_time
Maximum time for the shutdown operation.
Definition: shutdowner.hpp:791
shutdowner_guard_t(so_5::mbox_t notify_mbox)
Initializing constructor.
Definition: shutdowner.hpp:71
A special mbox which must be used for notification about shutdown operation.
Definition: shutdowner.hpp:375
virtual void drop_delivery_filter(const std::type_index &, agent_t &) noexcept override
Definition: shutdowner.hpp:185
virtual void do_deliver_service_request(const std::type_index &, const message_ref_t &, unsigned int) const override
Definition: shutdowner.hpp:163
status::deferred_action_t do_event_unsubscripton(agent_t *subscriber)
Main unsubscription actions.
Definition: shutdowner.hpp:557
value_t
Avaliable statuses of shutdown operation.
Definition: shutdowner.hpp:250
virtual void subscribe_event_handler(const std::type_index &type_index, const message_limit::control_block_t *limit, agent_t *subscriber) override
Definition: shutdowner.hpp:412
void do_event_subscription(const message_limit::control_block_t *limit, agent_t *subscriber)
Main subscription actions.
Definition: shutdowner.hpp:533
notify_mbox_t(outliving_reference_t< environment_t > env, mbox_t time_elapsed_mbox, std::chrono::steady_clock::duration max_shutdown_time, mbox_id_t id, Tracing_Base_Args &&...tracing_args)
Definition: shutdowner.hpp:382
const int rc_illegal_msg_type
An attempt to use illegal message type.
Definition: shutdowner.hpp:35
mbox_t m_time_elapsed_mbox
Mbox to be used for delayed shutdown_time_elapsed message.
Definition: shutdowner.hpp:340
virtual mbox_t notify_mbox() const =0
Get a mbox which can be used for subscription to shutdown_initiated message.
virtual void set_delivery_filter(const std::type_index &, const delivery_filter_t &, agent_t &) override
Definition: shutdowner.hpp:174
virtual void do_deliver_service_request(const std::type_index &msg_type, const message_ref_t &, unsigned int) const override
Definition: shutdowner.hpp:464
const mbox_id_t m_id
Unique ID of that mbox.
Definition: shutdowner.hpp:502
virtual void drop_delivery_filter(const std::type_index &, agent_t &) noexcept override
Definition: shutdowner.hpp:487
deferred_action_t
Which action must be performed after updating status of shutdown operation.
Definition: shutdowner.hpp:266
virtual void do_deliver_message(const std::type_index &, const message_ref_t &, unsigned int) const override
Definition: shutdowner.hpp:150
const int rc_subscription_disabled_during_shutdown
Subscription to shutdowner mbox when shutdown in progess is prohibited.
Definition: shutdowner.hpp:42
subscriber_info_t(agent_t *subscriber, const message_limit::control_block_t *limits)
Initializing constructor.
Definition: shutdowner.hpp:219
layer_template_t(std::chrono::steady_clock::duration shutdown_time)
Initializing constructor.
Definition: shutdowner.hpp:761
timer_id_t m_shutdown_timer
Timer ID for shutdown_time_elapsed message.
Definition: shutdowner.hpp:351
virtual std::string query_name() const override
Definition: shutdowner.hpp:438
virtual void unsubscribe_event_handlers(const std::type_index &, agent_t *) override
Definition: shutdowner.hpp:126
Special object to change the status and detect deferred action to be performed.
Definition: shutdowner.hpp:290
void start_shutdown_clock() const
Initiate delayed shutdown_time_elapsed message.
Definition: shutdowner.hpp:685
virtual mbox_type_t type() const override
Definition: shutdowner.hpp:446
Shutdown is started but there are some pending subscribers.
All subscribers are unsubscribed. Shutdown can and should be completed.
outliving_reference_t< environment_t > m_env
SObjectizer Environment to work in.
Definition: shutdowner.hpp:496
static void ensure_valid_message_type(const std::type_index &type_index)
Check for valid type of message to be handled.
Definition: shutdowner.hpp:519
virtual void do_deliver_message(const std::type_index &msg_type, const message_ref_t &message, unsigned int) const override
Definition: shutdowner.hpp:452
time_elapsed_mbox_t(outliving_reference_t< environment_t > env, mbox_id_t id)
Initializing constructor.
Definition: shutdowner.hpp:98
notify_mbox_data_t(mbox_t time_elapsed_mbox, std::chrono::steady_clock::duration max_shutdown_time)
Initializing constructor.
Definition: shutdowner.hpp:354
outliving_reference_t< holder_t > m_status
Definition: shutdowner.hpp:292
Special mbox to receive and handle a signal about time limit.
Definition: shutdowner.hpp:93
inline ::so_5::extra::shutdowner::layer_t & layer(::so_5::environment_t &env)
A helper function to receive a reference to shutdowner layer.
Definition: shutdowner.hpp:929
status::deferred_action_t do_initiate_shutdown(const std::type_index &msg_type, const message_ref_t &message) const
Do all necessary actions for start of shutdown operation.
Definition: shutdowner.hpp:609
void send_shutdown_initated_to_all(const std::type_index &msg_type, const message_ref_t &message) const
Send shutdown_initiated message to all actual subscribers.
Definition: shutdowner.hpp:640