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