CatapultServer  v0.5.0.1 (Elephant)
TimedCallback.h
Go to the documentation of this file.
1 
21 #pragma once
24 #include "catapult/functions.h"
25 #include <boost/asio/steady_timer.hpp>
26 #include <memory>
27 
28 namespace catapult { namespace thread {
29 
32  template<typename TCallback, typename... TCallbackArgs>
34  : public std::enable_shared_from_this<StrandedTimedCallback<TCallback, TCallbackArgs...>> {
35  private:
37 
38  private:
40  template<typename TCallbackWrapper>
42  public:
44  TCallbackWrapper& wrapper,
45  boost::asio::io_context& ioContext,
46  const TCallback& callback,
47  TCallbackArgs&&... timeoutArgs)
48  : m_wrapper(wrapper)
50  , m_timeoutArgs(std::forward<TCallbackArgs>(timeoutArgs)...)
51  , m_timer(ioContext)
52  , m_isCallbackInvoked(false)
53  , m_isTimedOut(false)
54  {}
55 
56  public:
57  void setTimeout(const utils::TimeSpan& timeout) {
58  m_timer.expires_from_now(std::chrono::milliseconds(timeout.millis()));
59  m_timer.async_wait(m_wrapper.wrap([this](const auto&) {
60  this->handleTimedOut();
61  }));
62  }
63 
64  void setTimeoutHandler(const TimeoutHandlerType& handler) {
65  // if the callback was not already executed, save the handler for later
66  if (!m_isCallbackInvoked) {
67  m_timeoutHandler = handler;
68  return;
69  }
70 
71  // if this callback is already timed out, immediately execute the handler before returning
72  if (m_isTimedOut)
73  handler();
74  }
75 
76  bool callback(const std::tuple<TCallbackArgs...>& args) {
78  return false;
79 
80  m_isCallbackInvoked = true;
81 
82  // destroy the callback after this function returns
83  TCallback callback;
84  m_callback.swap(callback);
85 
86  callback(std::get<TCallbackArgs>(args)...);
87  m_timer.cancel();
88  return true;
89  }
90 
91  private:
92  void handleTimedOut() {
93  // destroy the timeout handler after this function returns
94  TimeoutHandlerType timeoutHandler;
95  m_timeoutHandler.swap(timeoutHandler);
96 
97  if (!callback(m_timeoutArgs))
98  return;
99 
100  m_isTimedOut = true;
101  if (timeoutHandler)
102  timeoutHandler();
103  }
104 
105  private:
106  TCallbackWrapper& m_wrapper;
107  TCallback m_callback;
108  std::tuple<TCallbackArgs...> m_timeoutArgs;
109 
110  boost::asio::steady_timer m_timer;
114  };
115 
116  public:
119  StrandedTimedCallback(boost::asio::io_context& ioContext, const TCallback& callback, TCallbackArgs&&... timeoutArgs)
120  : m_impl(*this, ioContext, callback, std::forward<TCallbackArgs>(timeoutArgs)...)
121  , m_strand(ioContext)
123  {}
124 
125  public:
127  void setTimeout(const utils::TimeSpan& timeout) {
128  post([timeout](auto& impl) { impl.setTimeout(timeout); });
129  }
130 
132  void setTimeoutHandler(const TimeoutHandlerType& handler) {
133  post([handler](auto& impl) { impl.setTimeoutHandler(handler); });
134  }
135 
137  template<typename... TArgs>
138  void callback(TArgs&&... args) {
139  // note that this function needs to be TArgs instead of TCallbackArgs so that it can be called
140  // with different qualifiers - e.g. when constructing, a timeoutArg might be passed by value
141  // but here it might be passed by (const) reference
142  post([args = std::make_tuple(std::forward<TArgs>(args)...)](auto& impl) {
143  impl.callback(args);
144  });
145  }
146 
147  public:
148  template<typename THandler>
149  auto wrap(THandler handler) {
150  return m_strandWrapper.wrap(this->shared_from_this(), handler);
151  }
152 
153  private:
154  template<typename THandler>
155  void post(THandler handler) {
156  return m_strandWrapper.post(this->shared_from_this(), [handler](const auto& pThis) {
157  handler(pThis->m_impl);
158  });
159  }
160 
161  private:
163  boost::asio::io_context::strand m_strand;
165  };
166 
169  template<typename TCallback, typename... TCallbackArgs>
170  auto MakeTimedCallback(boost::asio::io_context& ioContext, TCallback callback, TCallbackArgs&&... timeoutArgs) {
171  return std::make_shared<StrandedTimedCallback<TCallback, TCallbackArgs...>>(
172  ioContext,
173  callback,
174  std::forward<TCallbackArgs>(timeoutArgs)...);
175  }
176 }}
catapult::thread::StrandedTimedCallback::StrandedTimedCallback
StrandedTimedCallback(boost::asio::io_context &ioContext, const TCallback &callback, TCallbackArgs &&... timeoutArgs)
Definition: TimedCallback.h:119
catapult::thread::StrandOwnerLifetimeExtender
Wraps a strand and automatically augments handlers to extend the lifetime of an owning object.
Definition: StrandOwnerLifetimeExtender.h:29
catapult::thread::StrandedTimedCallback::BasicTimedCallback::handleTimedOut
void handleTimedOut()
Definition: TimedCallback.h:92
catapult::thread::StrandedTimedCallback::m_strandWrapper
StrandOwnerLifetimeExtender< StrandedTimedCallback > m_strandWrapper
Definition: TimedCallback.h:164
catapult::thread::StrandedTimedCallback::m_impl
BasicTimedCallback< StrandedTimedCallback > m_impl
Definition: TimedCallback.h:162
catapult::thread::StrandedTimedCallback::BasicTimedCallback::BasicTimedCallback
BasicTimedCallback(TCallbackWrapper &wrapper, boost::asio::io_context &ioContext, const TCallback &callback, TCallbackArgs &&... timeoutArgs)
Definition: TimedCallback.h:43
catapult::thread::StrandedTimedCallback::BasicTimedCallback::setTimeoutHandler
void setTimeoutHandler(const TimeoutHandlerType &handler)
Definition: TimedCallback.h:64
catapult::thread::StrandedTimedCallback::post
void post(THandler handler)
Definition: TimedCallback.h:155
catapult::thread::StrandedTimedCallback::BasicTimedCallback::m_callback
TCallback m_callback
Definition: TimedCallback.h:107
functions.h
catapult::utils::TimeSpan
Represents a time duration.
Definition: TimeSpan.h:30
catapult::thread::StrandedTimedCallback::BasicTimedCallback::setTimeout
void setTimeout(const utils::TimeSpan &timeout)
Definition: TimedCallback.h:57
catapult::thread::StrandedTimedCallback::TimeoutHandlerType
action TimeoutHandlerType
Definition: TimedCallback.h:36
catapult::thread::StrandedTimedCallback::BasicTimedCallback::m_isCallbackInvoked
bool m_isCallbackInvoked
Definition: TimedCallback.h:111
catapult::thread::MakeTimedCallback
auto MakeTimedCallback(boost::asio::io_context &ioContext, TCallback callback, TCallbackArgs &&... timeoutArgs)
Definition: TimedCallback.h:170
catapult::thread::StrandedTimedCallback::BasicTimedCallback::m_timeoutArgs
std::tuple< TCallbackArgs... > m_timeoutArgs
Definition: TimedCallback.h:108
catapult::thread::StrandedTimedCallback::wrap
auto wrap(THandler handler)
Definition: TimedCallback.h:149
catapult::thread::StrandedTimedCallback::BasicTimedCallback
Wraps a callback with a timer using an implicit strand.
Definition: TimedCallback.h:41
catapult::thread::StrandedTimedCallback::m_strand
boost::asio::io_context::strand m_strand
Definition: TimedCallback.h:163
catapult::action
std::function< void()> action
An action function.
Definition: functions.h:27
catapult::utils::TimeSpan::millis
constexpr uint64_t millis() const
Returns the number of milliseconds.
Definition: TimeSpan.h:91
catapult::thread::StrandedTimedCallback::setTimeout
void setTimeout(const utils::TimeSpan &timeout)
Sets the timeout to timeout (starting from now).
Definition: TimedCallback.h:127
catapult::thread::StrandedTimedCallback
Definition: TimedCallback.h:33
catapult::thread::StrandedTimedCallback::BasicTimedCallback::m_timeoutHandler
TimeoutHandlerType m_timeoutHandler
Definition: TimedCallback.h:113
TimeSpan.h
catapult
Definition: AddressExtractionExtension.cpp:28
catapult::thread::StrandedTimedCallback::callback
void callback(TArgs &&... args)
Invokes the wrapped callback with args.
Definition: TimedCallback.h:138
catapult::thread::StrandedTimedCallback::setTimeoutHandler
void setTimeoutHandler(const TimeoutHandlerType &handler)
Sets the timeout handler to timeoutHandler.
Definition: TimedCallback.h:132
catapult::thread::StrandedTimedCallback::BasicTimedCallback::callback
bool callback(const std::tuple< TCallbackArgs... > &args)
Definition: TimedCallback.h:76
catapult::thread::StrandedTimedCallback::BasicTimedCallback::m_wrapper
TCallbackWrapper & m_wrapper
Definition: TimedCallback.h:106
StrandOwnerLifetimeExtender.h
catapult::thread::StrandedTimedCallback::BasicTimedCallback::m_timer
boost::asio::steady_timer m_timer
Definition: TimedCallback.h:110
catapult::thread::StrandedTimedCallback::BasicTimedCallback::m_isTimedOut
bool m_isTimedOut
Definition: TimedCallback.h:112