SObjectizer-5 Extra
pub.hpp
Go to the documentation of this file.
1 /*!
2  * \file
3  * \brief Implementation of revocable timers
4  *
5  * \since
6  * v.1.2.0
7  */
8 
9 #pragma once
10 
11 #include <so_5/h/version.hpp>
12 
13 #if (SO_5_VERSION < SO_5_VERSION_MAKE(5, 23, 0))
14  #error "SObjectizer v.5.5.23 or above is required"
15 #endif
16 
17 #include <so_5_extra/revocable_msg/pub.hpp>
18 
19 #include <so_5_extra/error_ranges.hpp>
20 
21 #include <so_5/h/timers.hpp>
22 #include <so_5/rt/h/enveloped_msg.hpp>
23 #include <so_5/rt/h/send_functions.hpp>
24 
25 #include <atomic>
26 
27 namespace so_5 {
28 
29 namespace extra {
30 
31 namespace revocable_timer {
32 
33 namespace details {
34 
35 //
36 // envelope_t
37 //
38 /*!
39  * \brief A special envelope to be used for revocable timer messages.
40  *
41  * Just a synonim for so_5::extra::revocable_msg::details::envelope_t.
42  *
43  * \since
44  * v.1.2.0
45  */
47 
48 } /* namespace details */
49 
50 namespace impl {
51 
52 // Just forward declaration. Definition will be below definition of timer_id_t.
53 struct timer_id_maker_t;
54 
55 } /* namespace impl */
56 
57 //
58 // timer_id_t
59 //
60 /*!
61  * \brief The ID of revocable timer message/signal.
62  *
63  * This type plays the same role as so_5::timer_id_t. But provide
64  * guaranteed revocation of delayed/periodic message/signal.
65  *
66  * There are several implementations of send_delayed() and send_periodic()
67  * functions in so_5::extra::revocable_timer namespace. They all return
68  * instances of timer_id_t.
69  *
70  * An instance of timer_id_t returned from send_delayed/send_periodic need
71  * to be store somewhere. Otherwise the timer message will be revoked
72  * just after completion of send_delayed/send_periodic function. It is
73  * because the destructor of timer_id_t will be called and that destructor
74  * revokes the timer message.
75  *
76  * An instance of timer_id_t can be used for revocation of a timer message.
77  * Revocation can be performed by two ways:
78  *
79  * 1. Destructor of timer_id_t automatically revokes the timer message.
80  * 2. Method timer_id_t::release() or timer_id_t::revoke() is called
81  * by an user.
82  *
83  * For example:
84  * \code
85  * namespace timer_ns = so_5::extra::revocable_timer;
86  * void demo(so_5::mchain_t work_queue) {
87  * // Send a delayed demand to work queue and store the ID returned.
88  * auto id = timer_ns::send_delayed<flush_data>(work_queue, 10s, ...);
89  * ... // Do some work.
90  * if(some_condition)
91  * // Our previous message should be revoked if it is not delivered yet.
92  * id.release();
93  * ...
94  * // Message will be automatically revoked here because ID is destroyed
95  * // on leaving the scope.
96  * }
97  * \endcode
98  *
99  * \note
100  * The timer_id_t is Movable, not Copyable.
101  *
102  * \attention
103  * This is not a thread-safe class. It means that it is dangerous to
104  * call methods of that class (like revoke() or is_active()) from
105  * different threads at the same time.
106  *
107  * \since
108  * v.1.2.0
109  */
110 class timer_id_t final
111  {
113 
114  private :
115  //! The envelope that was sent.
116  /*!
117  * \note Can be nullptr if default constructor was used.
118  */
120 
121  //! Timer ID for the envelope.
123 
125  ::so_5::intrusive_ptr_t< details::envelope_t > envelope,
126  ::so_5::timer_id_t actual_id )
127  : m_envelope{ std::move(envelope) }
129  {}
130 
131  public :
132  timer_id_t() = default;
133  /*!
134  * \note The destructor automatically revokes the message if it is
135  * not delivered yet.
136  */
137  ~timer_id_t() noexcept
138  {
139  release();
140  }
141 
142  // This class is not copyable.
143  timer_id_t( const timer_id_t & ) = delete;
144  timer_id_t & operator=( const timer_id_t & ) = delete;
145 
146  // But this class is moveable.
147  timer_id_t( timer_id_t && ) noexcept = default;
148  timer_id_t & operator=( timer_id_t && ) noexcept = default;
149 
150  friend void
151  swap( timer_id_t & a, timer_id_t & b ) noexcept
152  {
153  a.m_envelope.swap( b.m_envelope );
154  a.m_actual_id.swap( b.m_actual_id );
155  }
156 
157  //! Is message delivery still in progress?
158  /*!
159  * \note Please take care when using this method.
160  * Message delivery in SObjectizer is asynchronous operation.
161  * It means that you can receve \a true from is_active() but
162  * this value will already be obsolete because the message
163  * can be delivered just before return from is_active().
164  * The return value of is_active() can be useful in that context:
165  * \code
166  * namespace timer_ns = so_5::extra::revocable_timer;
167  * void demo(so_5::mchain_t work_queue) {
168  * auto id = timer_ns::send_delayed(work_queue, 10s, ...);
169  * ... // Do some work.
170  * if(some_condition)
171  * id.revoke();
172  * ... // Do some more work.
173  * if(another_condition)
174  * id.revoke();
175  * ...
176  * if(id.is_active()) {
177  * // No previous calls to revoke().
178  * ...
179  * }
180  * }
181  * \endcode
182  */
183  bool
184  is_active() const noexcept
185  {
186  return m_actual_id.is_active();
187  }
188 
189  //! Revoke the message and release the timer.
190  /*!
191  * \note
192  * It is safe to call release() for already revoked message.
193  */
194  void
195  release() noexcept
196  {
197  if( m_envelope )
198  {
199  m_envelope->revoke();
200  m_actual_id.release();
201 
202  m_envelope.reset();
203  }
204  }
205 
206  //! Revoke the message and release the timer.
207  /*!
208  * Just a synonym for release() method.
209  */
210  void
211  revoke() noexcept { release(); }
212  };
213 
214 namespace impl {
215 
216 /*
217  * This is helper for creation of initialized timer_id objects.
218  */
220  {
221  template< typename... Args >
222  SO_5_NODISCARD static auto
223  make( Args && ...args )
224  {
225  return ::so_5::extra::revocable_timer::timer_id_t{
226  std::forward<Args>(args)... };
227  }
228  };
229 
230 /*
231  * Helper function for actual sending of periodic message.
232  */
237  const so_5::mbox_t & to,
238  const std::type_index & msg_type,
242  {
244 
247 
249  msg_type,
250  envelope,
251  to,
252  pause,
253  period );
254 
255  return timer_id_maker_t::make(
257  }
258 
259 /*
260  * This is helpers for send_delayed and send_periodic implementation.
261  */
262 
263 template< class Message, bool Is_Signal >
265  {
266  template< typename... Args >
269  ::so_5::environment_t & env,
270  const ::so_5::mbox_t & to,
273  Args &&... args )
274  {
277  std::forward< Args >( args )...)
278  };
279 
281 
283  env,
284  to,
286  std::move(payload),
287  pause,
288  period );
289  }
290  };
291 
292 template< class Message >
293 struct instantiator_and_sender_base< Message, true >
294  {
295  //! Type of signal to be delivered.
297 
301  const so_5::mbox_t & to,
304  {
306  env,
307  to,
309  message_ref_t{},
310  pause,
311  period );
312  }
313  };
314 
315 template< class Message >
318  Message,
320  {};
321 
322 } /* namespace impl */
323 
324 /*!
325  * \brief A utility function for creating and delivering a periodic message.
326  *
327  * This function requires passing a reference to SObjectizer Environment and
328  * target mbox. Because of that it usually used outside SObjectizer's agent
329  * (where it is possible to use another variant of send_periodic). For
330  * example:
331  * \code
332  * so_5::wrapped_env_t sobj; // SObjectizer is started here.
333  * so_5::mbox_t worker_mbox; // Will get a value later.
334  * // Create a worker and get its mbox.
335  * sobj.environment().introduce_coop( [&](so_5::coop_t & coop) {
336  * auto worker = coop.make_agent<worker_agent>(...);
337  * worker_mbox = worker->so_direct_mbox();
338  * });
339  * // Send revocable periodic message to the worker.
340  * auto timer_id = so_5::extra::revocable_timer::send_periodic<tell_status>(
341  * sobj.environment(),
342  * worker_mbox(),
343  * 1s, 1s,
344  * ... );
345  * ... // Do some work.
346  * // Revoke the tell_status message.
347  * timer_id.release();
348  * \endcode
349  *
350  * \note
351  * The return value of that function must be stored somewhere. Otherwise
352  * the periodic timer will be cancelled automatically just right after
353  * send_periodic returns.
354  *
355  * \attention
356  * Values of \a pause and \a period should be non-negative.
357  *
358  * \since
359  * v.1.2.0
360  *
361  */
362 template< typename Message, typename... Args >
363 SO_5_NODISCARD timer_id_t
365  //! An environment to be used for timer.
367  //! Mbox for the message to be sent to.
368  const so_5::mbox_t & to,
369  //! Pause for message delaying.
371  //! Period of message repetitions.
373  //! Message constructor parameters.
374  Args&&... args )
375  {
376  return impl::instantiator_and_sender< Message >::send_periodic(
377  env, to, pause, period, std::forward< Args >( args )... );
378  }
379 
380 /*!
381  * \brief A utility function for creating and delivering a periodic message
382  * to the specified destination.
383  *
384  * Agent, ad-hoc agent or mchain can be used as \a target.
385  *
386  * \note
387  * Message chains with overload control must be used for periodic messages
388  * with additional care because exceptions can't be thrown during
389  * dispatching messages from timer.
390  *
391  * This function is intended to be used inside SObjectizer's agents where
392  * we have `this` pointer and can extract reference to SObjectizer
393  * Environment and the direct mbox of agent from that pointer:
394  * \code
395  * namespace timer_ns = so_5::extra::revocable_timer;
396  * class my_agent : public so_5::agent_t {
397  * timer_ns::timer_id_t timer_;
398  * ...
399  * void so_evt_start() override {
400  * ...
401  * // Initiate a periodic message to self.
402  * timer_ = timer_ns::send_periodic<do_some_task>(*this, 1s, 1s, ...);
403  * ...
404  * }
405  * ...
406  * };
407  * \endcode
408  *
409  * \note
410  * The return value of that function must be stored somewhere. Otherwise
411  * the periodic timer will be cancelled automatically just right after
412  * send_periodic returns.
413  *
414  * \attention
415  * Values of \a pause and \a period should be non-negative.
416  *
417  * \tparam Message type of message or signal to be sent.
418  * \tparam Target can be so_5::agent_t, so_5::adhoc_agent_definition_proxy_t or
419  * so_5::mchain_t.
420  * \tparam Args list of arguments for Message's constructor.
421  *
422  * \since
423  * v.1.2.0
424  */
425 template< typename Message, typename Target, typename... Args >
426 SO_5_NODISCARD timer_id_t
428  //! A destination for the periodic message.
429  Target && target,
430  //! Pause for message delaying.
432  //! Period of message repetitions.
434  //! Message constructor parameters.
435  Args&&... args )
436  {
437  return ::so_5::extra::revocable_timer::send_periodic< Message >(
438  ::so_5::send_functions_details::arg_to_env( target ),
439  ::so_5::send_functions_details::arg_to_mbox( target ),
440  pause,
441  period,
442  std::forward< Args >(args)... );
443  }
444 
445 /*!
446  * \brief A utility function for delivering a periodic
447  * from an existing message hood.
448  *
449  * \attention Message must not be a mutable message if \a period is not 0.
450  * Otherwise an exception will be thrown.
451  *
452  * \tparam Message a type of message to be redirected (it can be
453  * in form of Msg, so_5::immutable_msg<Msg> or so_5::mutable_msg<Msg>).
454  *
455  * Usage example:
456  * \code
457  namespace timer_ns = so_5::extra::revocable_timer;
458  class redirector : public so_5::agent_t {
459  ...
460  void on_some_immutable_message(mhood_t<first_msg> cmd) {
461  timer_id = timer_ns::send_periodic(so_environment(), another_mbox,
462  std::chrono::seconds(1),
463  std::chrono::seconds(15),
464  cmd);
465  ...
466  }
467 
468  void on_some_mutable_message(mhood_t<mutable_msg<second_msg>> cmd) {
469  timer_id = timer_ns::send_periodic(so_environment(), another_mbox,
470  std::chrono::seconds(1),
471  std::chrono::seconds(20),
472  std::move(cmd));
473  // Note: cmd is nullptr now, it can't be used anymore.
474  ...
475  }
476  };
477  * \endcode
478  *
479  * \note
480  * The return value of that function must be stored somewhere. Otherwise
481  * the periodic timer will be cancelled automatically just right after
482  * send_periodic returns.
483  *
484  * \attention
485  * Values of \a pause and \a period should be non-negative.
486  *
487  * \since
488  * v.1.2.0
489  */
490 template< typename Message >
492 typename std::enable_if<
493  !::so_5::is_signal< Message >::value,
494  timer_id_t >::type
496  //! An environment to be used for timer.
497  ::so_5::environment_t & env,
498  //! Mbox for the message to be sent to.
499  const ::so_5::mbox_t & to,
500  //! Pause for message delaying.
502  //! Period of message repetitions.
504  //! Existing message hood for message to be sent.
505  ::so_5::mhood_t< Message > mhood )
506  {
508  env,
509  to,
512  pause,
513  period );
514  }
515 
516 /*!
517  * \brief A utility function for periodic redirection of a signal
518  * from existing message hood.
519  *
520  * \tparam Message a type of signal to be redirected (it can be
521  * in form of Sig or so_5::immutable_msg<Sig>).
522  *
523  * Usage example:
524  * \code
525  class redirector : public so_5::agent_t {
526  ...
527  void on_some_immutable_signal(mhood_t<some_signal> cmd) {
528  timer_id = so_5::extra::revocable_timer::send_periodic(
529  so_environment(),
530  another_mbox,
531  std::chrono::seconds(1),
532  std::chrono::seconds(10),
533  cmd);
534  ...
535  }
536  };
537  * \endcode
538  *
539  * \note
540  * The return value of that function must be stored somewhere. Otherwise
541  * the periodic timer will be cancelled automatically just right after
542  * send_periodic returns.
543  *
544  * \attention
545  * Values of \a pause and \a period should be non-negative.
546  *
547  * \since
548  * v.1.2.0
549  */
550 template< typename Message >
552 typename std::enable_if<
553  ::so_5::is_signal< Message >::value,
554  timer_id_t >::type
556  //! An environment to be used for timer.
557  ::so_5::environment_t & env,
558  //! Mbox for the message to be sent to.
559  const ::so_5::mbox_t & to,
560  //! Pause for message delaying.
562  //! Period of message repetitions.
564  //! Existing message hood for message to be sent.
565  ::so_5::mhood_t< Message > /*mhood*/ )
566  {
568  env,
569  to,
571  message_ref_t{},
572  pause,
573  period );
574  }
575 
576 /*!
577  * \brief A helper function for redirection of a message/signal as a periodic
578  * message/signal.
579  *
580  * This function can be used if \a target is a reference to agent or if
581  * \a target is a mchain. In such cases instead of writing:
582  * \code
583  * periodic_id = so_5::extra::revocable_timer::send_periodic(
584  * target_agent.so_environment(),
585  * target_agent.so_direct_mbox(),
586  * pause,
587  * period,
588  * std::move(msg));
589  * \endcode
590  * it is possible to write:
591  * \code
592  * periodic_id = so_5::extra::revocable_timer::send_periodic(
593  * target_agent,
594  * pause,
595  * period,
596  * std::move(msg));
597  * \endcode
598  *
599  * Example usage:
600  * \code
601  * namespace timer_ns = so_5::extra::revocable_timer;
602  * class my_agent : public so_5::agent_t {
603  * ...
604  * so_5::mchain_t target_mchain_;
605  * timer_ns::timer_id_t periodic_msg_id_;
606  * ...
607  * void on_some_msg(mhood_t<some_msg> cmd) {
608  * if( ... )
609  * // Message should be resend as a periodic message.
610  * periodic_msg_id_ = timer_ns::send_periodic(target_mchain_, 10s, 20s, std::move(cmd));
611  * }
612  * \endcode
613  *
614  * \note
615  * The return value of that function must be stored somewhere. Otherwise
616  * the periodic timer will be cancelled automatically just right after
617  * send_periodic returns.
618  *
619  * \attention
620  * Values of \a pause and \a period should be non-negative.
621  *
622  * \since
623  * v.1.2.0
624  */
625 template< typename Message, typename Target >
628  //! A target for periodic message/signal.
629  //! It can be a reference to a target agent or a mchain_t.
630  Target && target,
631  //! Pause for the first occurence of the message/signal.
633  //! Period of message repetitions.
635  //! Existing message hood for message/signal to be sent.
636  ::so_5::mhood_t< Message > mhood )
637  {
641  pause,
642  period,
643  std::move(mhood) );
644  }
645 
646 /*!
647  * \brief A utility function for creating and delivering a delayed message.
648  *
649  * This function requires passing a reference to SObjectizer Environment and
650  * target mbox. Because of that it usually used outside SObjectizer's agent
651  * (where it is possible to use another variant of send_delayed). For
652  * example:
653  * \code
654  * so_5::wrapped_env_t sobj; // SObjectizer is started here.
655  * so_5::mbox_t worker_mbox; // Will get a value later.
656  * // Create a worker and get its mbox.
657  * sobj.environment().introduce_coop( [&](so_5::coop_t & coop) {
658  * auto worker = coop.make_agent<worker_agent>(...);
659  * worker_mbox = worker->so_direct_mbox();
660  * });
661  * // Send revocable delayed message to the worker.
662  * auto timer_id = so_5::extra::revocable_timer::send_periodic<kill_yourself>(
663  * sobj.environment(),
664  * worker_mbox(),
665  * 60s,
666  * ... );
667  * ... // Do some work.
668  * // Revoke the kill_yourself message.
669  * timer_id.release();
670  * \endcode
671  *
672  * \note
673  * The return value of that function must be stored somewhere. Otherwise
674  * the delayed timer will be cancelled automatically just right after
675  * send_delayed returns.
676  *
677  * \attention
678  * Value of \a pause should be non-negative.
679  *
680  * \since
681  * v.1.2.0
682  */
683 template< typename Message, typename... Args >
686  //! An environment to be used for timer.
688  //! Mbox for the message to be sent to.
689  const so_5::mbox_t & to,
690  //! Pause for message delaying.
692  //! Message constructor parameters.
693  Args&&... args )
694  {
696  env,
697  to,
698  pause,
700  std::forward<Args>(args)... );
701  }
702 
703 /*!
704  * \brief A utility function for creating and delivering a delayed message
705  * to the specified destination.
706  *
707  * Agent, ad-hoc agent or mchain can be used as \a target.
708  *
709  * \note
710  * Message chains with overload control must be used for periodic messages
711  * with additional care because exceptions can't be thrown during
712  * dispatching messages from timer.
713  *
714  * This function is intended to be used inside SObjectizer's agents where
715  * we have `this` pointer and can extract reference to SObjectizer
716  * Environment and the direct mbox of agent from that pointer:
717  * \code
718  * namespace timer_ns = so_5::extra::revocable_timer;
719  * class my_agent : public so_5::agent_t {
720  * timer_ns::timer_id_t timer_;
721  * ...
722  * void so_evt_start() override {
723  * ...
724  * // Initiate a delayed message to self.
725  * timer_ = timer_ns::send_periodic<kill_youself>(*this, 60s, ...);
726  * ...
727  * }
728  * ...
729  * };
730  * \endcode
731  *
732  * \note
733  * The return value of that function must be stored somewhere. Otherwise
734  * the delayed timer will be cancelled automatically just right after
735  * send_delayed returns.
736  *
737  * \attention
738  * Value of \a pause should be non-negative.
739  *
740  * \tparam Message type of message or signal to be sent.
741  * \tparam Target can be so_5::agent_t, so_5::adhoc_agent_definition_proxy_t or
742  * so_5::mchain_t.
743  * \tparam Args list of arguments for Message's constructor.
744  *
745  * \since
746  * v.1.2.0
747  */
748 template< typename Message, typename Target, typename... Args >
751  //! A destination for the periodic message.
752  Target && target,
753  //! Pause for message delaying.
755  //! Message constructor parameters.
756  Args&&... args )
757  {
761  pause,
762  std::forward< Args >(args)... );
763  }
764 
765 /*!
766  * \brief A helper function for redirection of existing message/signal
767  * as delayed message.
768  *
769  * Usage example:
770  * \code
771  * namespace timer_ns = so_5::extra::revocable_timer;
772  * class my_agent : public so_5::agent_t {
773  * const so_5::mbox_t another_worker_;
774  * timer_ns::timer_id_t timer_;
775  * ...
776  * void on_some_msg(mhood_t<some_message> cmd) {
777  * // Redirect this message to another worker with delay in 250ms.
778  * timer_ = timer_ns::send_delayed(so_environment(),
779  * another_worker_,
780  * std::chrono::milliseconds(250),
781  * std::move(cmd));
782  * ...
783  * }
784  * };
785  * \endcode
786  *
787  * \note
788  * The return value of that function must be stored somewhere. Otherwise
789  * the delayed timer will be cancelled automatically just right after
790  * send_delayed returns.
791  *
792  * \attention
793  * Value of \a pause should be non-negative.
794  *
795  * \tparam Message type of message or signal to be sent.
796  *
797  * \since
798  * v.1.2.0
799  */
800 template< typename Message >
803  //! An environment to be used for timer.
805  //! Mbox for the message to be sent to.
806  const so_5::mbox_t & to,
807  //! Pause for message delaying.
809  //! Message to redirect.
810  ::so_5::mhood_t< Message > cmd )
811  {
813  env,
814  to,
815  pause,
817  std::move(cmd) );
818  }
819 
820 /*!
821  * \brief A helper function for redirection of existing message/signal
822  * as delayed message.
823  *
824  * Agent, ad-hoc agent or mchain can be used as \a target.
825  *
826  * Usage example:
827  * \code
828  * namespace timer_ns = so_5::extra::revocable_timer;
829  * class my_agent : public so_5::agent_t {
830  * const so_5::mchain_t work_queue_;
831  * timer_ns::timer_id_t timer_;
832  * ...
833  * void on_some_msg(mhood_t<some_message> cmd) {
834  * // Redirect this message to another worker with delay in 250ms.
835  * timer_ = timer_ns::send_delayed(work_queue_,
836  * std::chrono::milliseconds(250),
837  * std::move(cmd));
838  * ...
839  * }
840  * };
841  * \endcode
842  *
843  * \note
844  * The return value of that function must be stored somewhere. Otherwise
845  * the delayed timer will be cancelled automatically just right after
846  * send_delayed returns.
847  *
848  * \attention
849  * Value of \a pause should be non-negative.
850  *
851  * \tparam Message type of message or signal to be sent.
852  *
853  * \since
854  * v.1.2.0
855  */
856 template< typename Message, typename Target >
859  //! A destination for the periodic message.
860  Target && target,
861  //! Pause for message delaying.
863  //! Message to redirect.
864  ::so_5::mhood_t< Message > cmd )
865  {
868  pause,
870  std::move(cmd) );
871  }
872 
873 } /* namespace revocable_timer */
874 
875 } /* namespace extra */
876 
877 } /* namespace so_5 */
SO_5_NODISCARD timer_id_t send_delayed(Target &&target, std::chrono::steady_clock::duration pause, ::so_5::mhood_t< Message > cmd)
A helper function for redirection of existing message/signal as delayed message.
Definition: pub.hpp:858
timer_id_t & operator=(const timer_id_t &)=delete
friend void swap(timer_id_t &a, timer_id_t &b) noexcept
Definition: pub.hpp:151
Ranges for error codes of each submodules.
Definition: details.hpp:14
timer_id_t(timer_id_t &&) noexcept=default
timer_id_t(::so_5::intrusive_ptr_t< details::envelope_t > envelope, ::so_5::timer_id_t actual_id)
Definition: pub.hpp:124
static SO_5_NODISCARD auto make(Args &&...args)
Definition: pub.hpp:223
void release() noexcept
Revoke the message and release the timer.
Definition: pub.hpp:195
timer_id_t & operator=(timer_id_t &&) noexcept=default
void revoke() noexcept
Revoke the message and release the timer.
Definition: pub.hpp:211
bool is_active() const noexcept
Is message delivery still in progress?
Definition: pub.hpp:184
SO_5_NODISCARD timer_id_t send_periodic(Target &&target, std::chrono::steady_clock::duration pause, std::chrono::steady_clock::duration period, Args &&... args)
A utility function for creating and delivering a periodic message to the specified destination...
Definition: pub.hpp:427
SO_5_NODISCARD so_5::extra::revocable_timer::timer_id_t make_envelope_and_initiate_timer(so_5::environment_t &env, const so_5::mbox_t &to, const std::type_index &msg_type, message_ref_t payload, std::chrono::steady_clock::duration pause, std::chrono::steady_clock::duration period)
Definition: pub.hpp:235
::so_5::intrusive_ptr_t< details::envelope_t > m_envelope
The envelope that was sent.
Definition: pub.hpp:119
::so_5::timer_id_t m_actual_id
Timer ID for the envelope.
Definition: pub.hpp:122
SO_5_NODISCARD timer_id_t send_periodic(so_5::environment_t &env, const so_5::mbox_t &to, std::chrono::steady_clock::duration pause, std::chrono::steady_clock::duration period, Args &&... args)
A utility function for creating and delivering a periodic message.
Definition: pub.hpp:364
timer_id_t(const timer_id_t &)=delete
static SO_5_NODISCARD ::so_5::extra::revocable_timer::timer_id_t send_periodic(::so_5::environment_t &env, const ::so_5::mbox_t &to, std::chrono::steady_clock::duration pause, std::chrono::steady_clock::duration period, Args &&... args)
Definition: pub.hpp:268