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 #include <so_5/impl/message_limit_internals.hpp>
12 #include <so_5/impl/agent_ptr_compare.hpp>
13 
14 #include <so_5/details/sync_helpers.hpp>
15 
16 #include <so_5/mbox.hpp>
17 #include <so_5/send_functions.hpp>
18 
19 #include <so_5/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  mbox_id_t
109  id() const override
110  {
111  return m_id;
112  }
113 
114  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  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  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 
144  type() const override
145  {
146  return mbox_type_t::multi_producer_single_consumer;
147  }
148 
149  void
151  const std::type_index & /*msg_type*/,
152  const message_ref_t & /*message*/,
153  unsigned int /*overlimit_reaction_deep*/ ) 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  void
164  const std::type_index & /*msg_type*/,
165  const delivery_filter_t & /*filter*/,
166  agent_t & /*subscriber*/ ) override
167  {
168  SO_5_THROW_EXCEPTION( rc_not_implemented,
169  "set_delivery_filter is not implemented for "
170  "time_elapsed_mbox" );
171  }
172 
173  void
175  const std::type_index & /*msg_type*/,
176  agent_t & /*subscriber*/ ) noexcept override
177  {
178  /* Nothing to do. */
179  }
180 
181  environment_t &
182  environment() const noexcept override
183  {
184  return m_env.get();
185  }
186 
187  private :
188  //! SOEnv to work in.
190  //! Unique ID of that mbox.
192  };
193 
194 //
195 // subscriber_info_t
196 //
197 /*!
198  * \brief Description of one subscriber.
199  */
201  {
202  //! Actual subscriber.
203  /*!
204  * Can't be nullptr.
205  */
207  //! Message limit for that subscriber.
208  /*!
209  * Can be nullptr if message limit is not used.
210  */
212 
213  //! Initializing constructor.
215  agent_t * subscriber,
216  const message_limit::control_block_t * limits )
218  , m_limits(limits)
219  {}
220 
221  //! Comparison operator.
222  /*!
223  * Compares only pointers to m_subscriber with respects
224  * to agent's priority.
225  */
226  bool
227  operator<( const subscriber_info_t & o ) const
228  {
229  return ::so_5::impl::special_agent_ptr_compare(
230  *m_subscriber, *(o.m_subscriber) );
231  }
232  };
233 
234 //
235 // subscriber_container_t
236 //
237 /*!
238  * \brief Type of subscriber's container.
239  */
241 
242 namespace status {
243 
244 //! Avaliable statuses of shutdown operation.
245 enum class value_t
246  {
247  //! Shutdown is not started yet.
248  not_started,
249  //! Shutdown is started but there are some pending subscribers.
250  started,
251  //! All subscribers are unsubscribed.
252  //! Shutdown can and should be completed.
254  };
255 
257 constexpr const value_t started = value_t::started;
259 
260 //! Which action must be performed after updating status of shutdown operation.
262  {
263  //! No action is required.
264  do_nothing,
265  //! Shutdown action must be completed.
267  };
268 
269 //! Special object which holds status.
270 /*!
271  * Updates for the status are enabled only to instances of updater_t class.
272  */
273 class holder_t
274  {
275  friend class updater_t;
276 
278 
279  public :
280  value_t
281  current() const noexcept { return m_status; }
282  };
283 
284 //! Special object to change the status and detect deferred action to be performed.
286  {
289 
290  public :
292  outliving_reference_t< holder_t > status )
293  : m_status( status )
294  {}
295 
296  value_t
297  current() const noexcept { return m_status.get().current(); }
298 
299  void
300  update( value_t new_status ) noexcept
301  {
302  m_status.get().m_status = new_status;
303  if( value_t::must_be_completed == new_status )
305  else
307  }
308 
310  action() const noexcept { return m_action; }
311  };
312 
313 } /* namespace status */
314 
315 //
316 // notify_mbox_data_t
317 //
318 /*!
319  * \brief An internal data of notify_mbox.
320  *
321  * It is collected in separate struct to provide ability to mark
322  * object of that struct as mutable. It is necessary because some
323  * of abstract_message_box_t's methods are declared as const by
324  * historical reasons.
325  */
327 {
328  //! Status of the shutdown operation.
330 
331  //! List of actual subscribers.
333 
334  //! Mbox to be used for delayed shutdown_time_elapsed message.
336  //! A time for shutdown operation.
338 
339  //! Timer ID for shutdown_time_elapsed message.
340  /*!
341  * Will be used for canceling of delayed message when shutdown is
342  * completed.
343  *
344  * Will receive actual value only when shutdown operation started.
345  */
347 
348  //! Initializing constructor.
350  mbox_t time_elapsed_mbox,
351  std::chrono::steady_clock::duration max_shutdown_time )
354  {}
355 };
356 
357 //
358 // notify_mbox_t
359 //
360 /*!
361  * \brief A special mbox which must be used for notification about
362  * shutdown operation.
363  *
364  * \tparam Lock_Type type of lock to be used for thread safety
365  * \tparam Tracing_Base type that implements message tracing stuff
366  * It is expected to be so_5::impl::msg_tracing_helpers::tracing_enabled_base
367  * or so_5::impl::msg_tracing_helpers::tracing_disabled_base
368  */
369 template< typename Lock_Type, typename Tracing_Base >
371  : public abstract_message_box_t
373  , private Tracing_Base
374  {
375  public :
376  template< typename... Tracing_Base_Args >
378  //! SObjectizer Environment to work in.
379  outliving_reference_t< environment_t > env,
380  //! A mbox for delayed message shutdown_time_elapsed_t.
381  mbox_t time_elapsed_mbox,
382  //! Time for the whole shutdown operation.
383  std::chrono::steady_clock::duration max_shutdown_time,
384  //! Unique ID of that mbox.
385  mbox_id_t id,
386  //! Params for tracing stuff.
387  Tracing_Base_Args && ...tracing_args )
389  , m_env( env )
390  , m_id( id )
392  {
393  // Now we can create and install shutdowner_guard to
394  // prevent SObjectizer from shutdown.
395  auto guard = std::make_shared< shutdowner_guard_t >( mbox_t(this) );
398  }
399 
400  mbox_id_t
401  id() const override
402  {
403  return m_id;
404  }
405 
406  void
408  const std::type_index & type_index,
409  const message_limit::control_block_t * limit,
410  agent_t & subscriber ) override
411  {
413  this->lock_and_perform( [&] {
415  } );
416  }
417 
418  void
420  const std::type_index & type_index,
421  agent_t & subscriber ) override
422  {
424  const auto action = this->lock_and_perform( [&] {
426  } );
427 
430  }
431 
432  std::string
433  query_name() const override
434  {
436  ss << "<mbox:type=MPMC:shutdowner:id=" << m_id << ">";
437  return ss.str();
438  }
439 
441  type() const override
442  {
444  }
445 
446  void
448  const std::type_index & msg_type,
449  const message_ref_t & message,
450  unsigned int /*overlimit_reaction_deep*/ ) override
451  {
453  const auto action = do_initiate_shutdown( msg_type, message );
456  }
457 
458  void
460  const std::type_index & msg_type,
461  const delivery_filter_t & /*filter*/,
462  agent_t & /*subscriber*/ ) override
463  {
466  "unable to set delivery filter to shutdowner mbox" );
467  }
468 
469  void
471  const std::type_index & /*msg_type*/,
472  agent_t & /*subscriber*/ ) noexcept override
473  {
474  /* Nothing to do. */
475  }
476 
477  environment_t &
478  environment() const noexcept override
479  {
480  return m_env.get();
481  }
482 
483  private :
484  //! SObjectizer Environment to work in.
486 
487  //! Stop_guard which prevents SObjectizer from shutdown.
489 
490  //! Unique ID of that mbox.
492 
493  //! Actual mbox data.
495 
496  //! Check for valid type of message to be handled.
497  /*!
498  * \note
499  * Only shutdown_initiated_t message can be handled by that mbox type.
500  */
501  static void
502  ensure_valid_message_type( const std::type_index & type_index )
503  {
504  if( type_index != typeid(shutdown_initiated_t) )
507  "only shutdown_initiated_t message type is allowed to "
508  "be used with shutdowner mbox" );
509  }
510 
511  //! Main subscription actions.
512  /*!
513  * May throw if shutdown is in progress or already completed.
514  */
515  void
517  const message_limit::control_block_t * limit,
518  agent_t & subscriber )
519  {
523  "a creation of new subscription is disabled during "
524  "shutdown procedure" );
525 
527  auto it = std::lower_bound(
530  info );
532  }
533 
534  //! Main unsubscription actions.
535  /*!
536  * Returns the action to be performed (shutdown completion may be
537  * necessary).
538  */
540  do_event_unsubscripton( agent_t & subscriber )
541  {
544 
545  subscriber_info_t info{ &subscriber, nullptr };
546  auto it = std::lower_bound(
549  info );
550  if( it != std::end(m_data.m_subscribers) &&
551  it->m_subscriber == &subscriber )
552  {
554 
556  {
557  if( m_data.m_subscribers.empty() )
558  {
561  }
562  }
563  }
564 
565  return status_updater.action();
566  }
567 
568  //! Do all necessary actions for completion of shutdown.
569  void
571  {
573 
575  }
576 
577  //! Do all necessary actions for start of shutdown operation.
578  /*!
579  * Returns the action to be performed (shutdown completion may be
580  * necessary).
581  */
584  const std::type_index & msg_type,
585  const message_ref_t & message )
586  {
589 
590  if( status::not_started == updater.current() )
591  {
593  if( !m_data.m_subscribers.empty() )
594  {
597  }
598  else
599  {
601  }
602  }
603 
604  return updater.action();
605  }
606 
607  //! Send shutdown_initiated message to all actual subscribers.
608  void
610  const std::type_index & msg_type,
611  const message_ref_t & message )
612  {
613  constexpr unsigned int overlimit_reaction_deep = 0u;
614 
616  *this, // as Tracing_Base
617  *this, // as abstract_message_box_t
618  "deliver_message",
620 
621  for( const auto & subscriber : m_data.m_subscribers )
622  {
623  using namespace so_5::message_limit::impl;
624 
626  m_id,
629  msg_type,
630  message,
633  [&] {
635 
639  m_id,
640  msg_type,
641  message );
642  } );
643  }
644  }
645 
646  //! Initiate delayed shutdown_time_elapsed message.
647  void
649  {
653  std::chrono::milliseconds::zero() );
654  }
655  };
656 
657 } /* namespace details */
658 
659 //
660 // layer_t
661 //
662 /*!
663  * \brief An interface of shutdowner layer.
664  *
665  * This is a public interface of actual layer. An user should use only
666  * that interface when it want to work with shutdown layer.
667  *
668  * For example, to subscribe to shutdown_initiated_t message it is neccessary
669  * to receive a pointer/reference to layer_t and call notify_mbox() method:
670  * \code
671  * // To make a subscription to shutdown notification.
672  * class my_agent final : public so_5::agent_t {
673  * public :
674  * my_agent(context_t ctx) : so_5::agent_t(std::move(ctx)) {
675  * // Long way:
676  * so_5::extra::shutdowner::layer_t * s =
677  * so_environment().query_layer<so_5::extra::shutdowner::layer_t>();
678  * so_subscribe(s->notify_mbox()).event(&my_agent::on_shutdown);
679  *
680  * // Shortest way:
681  * so_subscribe(so_5::extra::shutdowner::layer(so_environment()).notify_mbox())
682  * .event(&my_agent::on_shutdown);
683  * ...
684  * }
685  * ...
686  * private :
687  * void on_shutdown(mhood_t<so_5::extra::shutdowner::shutdown_initiated_t>)
688  * {...}
689  * };
690  * \endcode
691  *
692  * To initiate shutdown it is necessary to call so_5::environment_t::stop()
693  * method:
694  * \code
695  * so_environment().stop();
696  * \endcode
697  */
698 class layer_t : public ::so_5::layer_t
699  {
700  public :
701  //! Get a mbox which can be used for subscription to
702  //! shutdown_initiated message.
703  virtual mbox_t
704  notify_mbox() const = 0;
705  };
706 
707 namespace details {
708 
709 //
710 // layer_template_t
711 //
712 /*!
713  * \brief A template-based implementation of shutdowner layer.
714  *
715  * \note
716  * It creates all shutdowner-related stuff in start() method.
717  */
718 template< typename Lock_Type >
720  {
721  public :
722  //! Initializing constructor.
724  //! Maximum time for the shutdown operation.
725  std::chrono::steady_clock::duration shutdown_time )
727  {}
728 
729  virtual mbox_t
730  notify_mbox() const override
731  {
732  return m_notify_mbox;
733  }
734 
735  virtual void
736  start() override
737  {
739  [&]( const mbox_creation_data_t & data ) {
741  } );
742 
744  [&]( const mbox_creation_data_t & data ) {
746  data,
747  std::move( time_elapsed_mbox ) );
748  } );
749  }
750 
751  private :
752  //! Maximum time for the shutdown operation.
754 
755  //! Notification mbox.
756  /*!
757  * Will be created in start() method. Until then it is a null pointer.
758  */
760 
761  //! Create mbox for delayed shutdown_time_elapsed message.
762  mbox_t
764  //! Parameters for the new mbox.
765  const mbox_creation_data_t & data )
766  {
767  return mbox_t( new details::time_elapsed_mbox_t(
769  data.m_id ) );
770  }
771 
772  //! Create notification mbox.
773  /*!
774  * A new mbox will be created with respect to message tracing stuff.
775  */
776  mbox_t
778  //! Parameters for the new mbox.
779  const mbox_creation_data_t & data,
780  //! A mbox to be used for delayed shutdown_time_elapsed message.
782  {
783  mbox_t result;
784 
786  {
787  using T = details::notify_mbox_t<
788  Lock_Type,
790  result = mbox_t( new T(
794  data.m_id,
795  data.m_tracer.get() ) );
796  }
797  else
798  {
799  using T = details::notify_mbox_t<
800  Lock_Type,
802  result = mbox_t( new T(
806  data.m_id ) );
807  }
808 
809  return result;
810  }
811  };
812 
813 } /* namespace details */
814 
815 //
816 // make_layer
817 //
818 /*!
819  * \brief Main function to create an instance of shutdowner layer.
820  *
821  * Usage example:
822  * \code
823  * // Creation of layer with default mutex type.
824  * so_5::launch([](so_5::environment_t & env) {...},
825  * [](so_5::environment_params_t & params) {
826  * params.add_layer( so_5::extra::shutdowner::make_layer<>(30s) );
827  * });
828  *
829  * // Creation of layer with user-provided spinlock type.
830  * so_5::launch([](so_5::environment_t & env) {...},
831  * [](so_5::environment_params_t & params) {
832  * params.add_layer( so_5::extra::shutdowner::make_layer<my_spinlock_t>(30s));
833  * });
834  *
835  * // Creation of layer with null_mutex.
836  * // Note: null_mutex must be used only for non thread-safe environments.
837  * so_5::launch([](so_5::environment_t & env) {...},
838  * [](so_5::environment_params_t & params) {
839  * // Use single-threaded and not thread-safe environment.
840  * params.infrastructure_factory(
841  * so_5::env_infrastructures::simple_not_mtsafe::factory());
842  * // Shutdowner layer with null_mutex can be used in that environment.
843  * params.add_layer( so_5::extra::shutdowner::make_layer<so_5::null_mutex_t>(30s));
844  * });
845  * \endcode
846  *
847  * \tparam Lock_Type type of lock to be used for thread safety.
848  */
849 template< typename Lock_Type = std::mutex >
852  //! A maximum time for timeout operation.
854  {
857  shutdown_max_time ) );
858 
859  return result;
860  }
861 
862 //
863 // layer
864 //
865 /*!
866  * \brief A helper function to receive a reference to shutdowner layer.
867  *
868  * Usage example:
869  * \code
870  * // To make a subscription to shutdown notification.
871  * class my_agent final : public so_5::agent_t {
872  * public :
873  * my_agent(context_t ctx) : so_5::agent_t(std::move(ctx)) {
874  * auto & s = so_5::extra::shutdowner::layer( so_environment() );
875  * so_subscribe( s.notify_mbox() ).event( &my_agent::on_shutdown );
876  * ...
877  * }
878  * ...
879  * private :
880  * void on_shutdown(mhood_t<so_5::extra::shutdowner::shutdown_initiated_t>)
881  * {...}
882  * };
883  *
884  * // To initiate shutdown.
885  * so_5::extra::shutdowner::layer(env).initiate_shutdown();
886  * \endcode
887  *
888  * \note May throw an exception if shutdowner layer is not defined.
889  */
890 inline ::so_5::extra::shutdowner::layer_t &
891 layer( ::so_5::environment_t & env )
892  {
893  return *(env.query_layer< ::so_5::extra::shutdowner::layer_t >());
894  }
895 
896 } /* namespace shutdowner */
897 
898 } /* namespace extra */
899 
900 } /* namespace so_5 */
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:211
An interface of shutdowner layer.
Definition: shutdowner.hpp:698
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:730
subscriber_container_t m_subscribers
List of actual subscribers.
Definition: shutdowner.hpp:332
void drop_delivery_filter(const std::type_index &, agent_t &) noexcept override
Definition: shutdowner.hpp:470
void do_event_subscription(const message_limit::control_block_t *limit, agent_t &subscriber)
Main subscription actions.
Definition: shutdowner.hpp:516
status::holder_t m_status
Status of the shutdown operation.
Definition: shutdowner.hpp:329
environment_t & environment() const noexcept override
Definition: shutdowner.hpp:182
Implementation of stop_guard for shutdowner&#39;s purposes.
Definition: shutdowner.hpp:64
stop_guard_shptr_t m_shutdowner_guard
Stop_guard which prevents SObjectizer from shutdown.
Definition: shutdowner.hpp:488
const mbox_id_t m_id
Unique ID of that mbox.
Definition: shutdowner.hpp:191
mbox_t do_make_time_elapsed_mbox(const mbox_creation_data_t &data)
Create mbox for delayed shutdown_time_elapsed message.
Definition: shutdowner.hpp:763
const std::chrono::steady_clock::duration m_max_shutdown_time
A time for shutdown operation.
Definition: shutdowner.hpp:337
outliving_reference_t< environment_t > m_env
SOEnv to work in.
Definition: shutdowner.hpp:189
void drop_delivery_filter(const std::type_index &, agent_t &) noexcept override
Definition: shutdowner.hpp:174
updater_t(outliving_reference_t< holder_t > status)
Definition: shutdowner.hpp:291
Special object which holds status.
Definition: shutdowner.hpp:273
void unsubscribe_event_handlers(const std::type_index &, agent_t &) override
Definition: shutdowner.hpp:126
environment_t & environment() const noexcept override
Definition: shutdowner.hpp:478
void subscribe_event_handler(const std::type_index &type_index, const message_limit::control_block_t *limit, agent_t &subscriber) override
Definition: shutdowner.hpp:407
notify_mbox_data_t m_data
Actual mbox data.
Definition: shutdowner.hpp:494
void set_delivery_filter(const std::type_index &, const delivery_filter_t &, agent_t &) override
Definition: shutdowner.hpp:163
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:851
Ranges for error codes of each submodules.
Definition: details.hpp:13
A template-based implementation of shutdowner layer.
Definition: shutdowner.hpp:719
void update(value_t new_status) noexcept
Definition: shutdowner.hpp:300
mbox_t do_make_notification_mbox(const mbox_creation_data_t &data, mbox_t time_elapsed_mbox)
Create notification mbox.
Definition: shutdowner.hpp:777
bool operator<(const subscriber_info_t &o) const
Comparison operator.
Definition: shutdowner.hpp:227
void unsubscribe_event_handlers(const std::type_index &type_index, agent_t &subscriber) override
Definition: shutdowner.hpp:419
const std::chrono::steady_clock::duration m_shutdown_time
Maximum time for the shutdown operation.
Definition: shutdowner.hpp:753
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:370
value_t
Avaliable statuses of shutdown operation.
Definition: shutdowner.hpp:245
void do_deliver_message(const std::type_index &msg_type, const message_ref_t &message, unsigned int) override
Definition: shutdowner.hpp:447
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:377
void send_shutdown_initated_to_all(const std::type_index &msg_type, const message_ref_t &message)
Send shutdown_initiated message to all actual subscribers.
Definition: shutdowner.hpp:609
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:335
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:491
deferred_action_t
Which action must be performed after updating status of shutdown operation.
Definition: shutdowner.hpp:261
status::deferred_action_t do_initiate_shutdown(const std::type_index &msg_type, const message_ref_t &message)
Do all necessary actions for start of shutdown operation.
Definition: shutdowner.hpp:583
const int rc_subscription_disabled_during_shutdown
Subscription to shutdowner mbox when shutdown in progess is prohibited.
Definition: shutdowner.hpp:42
deferred_action_t action() const noexcept
Definition: shutdowner.hpp:310
void set_delivery_filter(const std::type_index &msg_type, const delivery_filter_t &, agent_t &) override
Definition: shutdowner.hpp:459
subscriber_info_t(agent_t *subscriber, const message_limit::control_block_t *limits)
Initializing constructor.
Definition: shutdowner.hpp:214
status::deferred_action_t do_event_unsubscripton(agent_t &subscriber)
Main unsubscription actions.
Definition: shutdowner.hpp:540
layer_template_t(std::chrono::steady_clock::duration shutdown_time)
Initializing constructor.
Definition: shutdowner.hpp:723
void subscribe_event_handler(const std::type_index &, const message_limit::control_block_t *, agent_t &) override
Definition: shutdowner.hpp:115
void complete_shutdown()
Do all necessary actions for completion of shutdown.
Definition: shutdowner.hpp:570
timer_id_t m_shutdown_timer
Timer ID for shutdown_time_elapsed message.
Definition: shutdowner.hpp:346
void start_shutdown_clock()
Initiate delayed shutdown_time_elapsed message.
Definition: shutdowner.hpp:648
Special object to change the status and detect deferred action to be performed.
Definition: shutdowner.hpp:285
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:485
static void ensure_valid_message_type(const std::type_index &type_index)
Check for valid type of message to be handled.
Definition: shutdowner.hpp:502
void do_deliver_message(const std::type_index &, const message_ref_t &, unsigned int) override
Definition: shutdowner.hpp:150
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:349
outliving_reference_t< holder_t > m_status
Definition: shutdowner.hpp:287
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:891
constexpr const value_t must_be_completed
Definition: shutdowner.hpp:258