RESTinio
so_timer_manager.hpp
Go to the documentation of this file.
1 /*
2  restinio
3 */
4 
5 /*!
6  Timers implementation with sobjectizer timers.
7 */
8 
9 #pragma once
10 
11 #include <restinio/asio_include.hpp>
12 #include <restinio/compiler_features.hpp>
13 
14 #include <so_5/all.hpp>
15 
16 namespace restinio
17 {
18 
19 namespace so5
20 {
21 
22 #if defined(SO_5_VERSION)
23  #if SO_5_VERSION < SO_5_VERSION_MAKE(6ull, 0ull, 0ull)
24  #define RESTINIO_USE_SO_5_5
25  #endif
26 #else
27  #define RESTINIO_USE_SO_5_5
28 #endif
29 
30 //
31 // msg_check_timer_t
32 //
33 
34 //! Check timer.
35 struct msg_check_timer_t final : public so_5::message_t
36 {
37  msg_check_timer_t( tcp_connection_ctx_weak_handle_t weak_handle )
39  {}
40 
42 };
43 
44 //
45 // so_timer_manager_t
46 //
47 
48 #if defined(RESTINIO_USE_SO_5_5)
49 
50 // The implementation of so_timer_manager for SO-5.5.
51 // SO-5.5 requires a reference to SObjectizer Environment for working with timers.
52 
53 //! Timer factory implementation using timers from SObjectizer.
54 class so_timer_manager_t final
55 {
56  public:
58  so_5::environment_t & env,
59  so_5::mbox_t mbox,
60  std::chrono::steady_clock::duration check_period )
61  : m_env{ env }
62  , m_mbox{ std::move( mbox ) }
64  {}
65 
66  //! Timer guard for async operations.
67  class timer_guard_t final
68  {
69  public:
71  so_5::environment_t & env,
72  so_5::mbox_t mbox,
73  std::chrono::steady_clock::duration check_period )
74  : m_env{ env }
75  , m_mbox{ std::move( mbox ) }
77  {}
78 
79  //! Schedule timeout check invocation.
80  void
81  schedule( tcp_connection_ctx_weak_handle_t weak_handle )
82  {
83  if( !m_current_op_timer.is_active() )
84  {
85  m_current_op_timer = so_5::send_periodic< msg_check_timer_t >(
86  m_env,
87  m_mbox,
88  m_check_period,
89  m_check_period,
90  std::move(weak_handle) );
91 
92  }
93  }
94 
95  //! Cancel timeout guard if any.
96  /*!
97  * @note
98  * Since v.0.6.0 this method is noexcept.
99  */
100  void
101  cancel() noexcept
102  {
103  RESTINIO_ENSURE_NOEXCEPT_CALL( m_current_op_timer.release() );
104  }
105 
106  private:
109 
112  //! \}
113  };
114 
115  // Create guard for connection.
116  timer_guard_t
118  {
119  return timer_guard_t{ m_env, m_mbox, m_check_period };
120  }
121 
122  //! Start/stop timer manager.
123  //! \{
124  void start() const noexcept {}
125  void stop() const noexcept {}
126  //! \}
127 
128  struct factory_t
129  {
133 
135  so_5::environment_t & env,
136  so_5::mbox_t mbox,
137  std::chrono::steady_clock::duration check_period = std::chrono::seconds{ 1 } )
138  : m_env{ env }
139  , m_mbox{ std::move( mbox ) }
141  {}
142 
143  auto
145  {
146  return std::make_shared< so_timer_manager_t >( m_env, m_mbox, m_check_period );
147  }
148  };
149 
150  private:
154 };
155 
156 #else
157 
158 // The implementation of so_timer_manager for SO-5.6 and newer.
159 // There is no need to hold a reference to SObjectizer Environment for working
160 // with timers.
161 
162 //! Timer factory implementation using timers from SObjectizer.
164 {
165  public:
167  so_5::mbox_t mbox,
169  : m_mbox{ std::move( mbox ) }
171  {}
172 
173  //! Timer guard for async operations.
174  class timer_guard_t final
175  {
176  public:
178  so_5::mbox_t mbox,
180  : m_mbox{ std::move( mbox ) }
182  {}
183 
184  //! Schedule timeout check invocation.
185  void
187  {
189  {
191  m_mbox,
194  std::move(weak_handle) );
195 
196  }
197  }
198 
199  //! Cancel timeout guard if any.
200  /*!
201  * @note
202  * Since v.0.6.0 this method is noexcept.
203  */
204  void
205  cancel() noexcept
206  {
208  }
209 
210  private:
211  const so_5::mbox_t m_mbox;
212 
215  //! \}
216  };
217 
218  // Create guard for connection.
221  {
223  }
224 
225  //! Start/stop timer manager.
226  //! \{
227  void start() const noexcept {}
228  void stop() const noexcept {}
229  //! \}
230 
231  struct factory_t
232  {
233  so_5::mbox_t m_mbox;
235 
236  factory_t(
237  so_5::mbox_t mbox,
239  : m_mbox{ std::move( mbox ) }
241  {}
242 
243  // This constructor is just for compatibility with previous versions.
244  factory_t(
245  so_5::environment_t &,
246  so_5::mbox_t mbox,
249  {}
250 
251  auto
252  create( asio_ns::io_context & ) const
253  {
255  }
256  };
257 
258  private:
259  so_5::mbox_t m_mbox;
261 };
262 #endif
263 
264 //
265 // a_timeout_handler_t
266 //
267 
268 //! Agent that handles timeouts.
269 class a_timeout_handler_t final
270  : public so_5::agent_t
271 {
273 
274  public:
275  a_timeout_handler_t( context_t ctx )
276  : so_base_type_t{ std::move( ctx ) }
277  {
278  so_subscribe_self()
279  .event(
280  []( const msg_check_timer_t & msg ){
281  if( auto h = msg.m_weak_handle.lock() )
282  h->check_timeout( h );
283  } );
284  }
285 };
286 
287 } /* namespace so5 */
288 
289 } /* namespace restinio */
timer_guard_t(so_5::environment_t &env, so_5::mbox_t mbox, std::chrono::steady_clock::duration check_period)
tcp_connection_ctx_weak_handle_t m_weak_handle
#define RESTINIO_USE_SO_5_5
const std::chrono::steady_clock::duration m_check_period
void cancel() noexcept
Cancel timeout guard if any.
const std::chrono::steady_clock::duration m_check_period
so_timer_manager_t(so_5::environment_t &env, so_5::mbox_t mbox, std::chrono::steady_clock::duration check_period)
std::enable_if< std::is_same< Parameter_Container, query_string_params_t >::value||std::is_same< Parameter_Container, router::route_params_t >::value, std::optional< Value_Type > >::type opt_value(const Parameter_Container &params, string_view_t key)
Gets the value of a parameter specified by key wrapped in std::optional<Value_Type> if parameter exis...
Definition: value_or.hpp:64
void schedule(tcp_connection_ctx_weak_handle_t weak_handle)
Schedule timeout check invocation.
void start() const noexcept
Start/stop timer manager.
auto create(asio_ns::io_context &) const
const std::chrono::steady_clock::duration m_check_period
msg_check_timer_t(tcp_connection_ctx_weak_handle_t weak_handle)
factory_t(so_5::environment_t &env, so_5::mbox_t mbox, std::chrono::steady_clock::duration check_period=std::chrono::seconds{ 1 })