CatapultServer  v0.5.0.1 (Elephant)
BriefServerRequestor.h
Go to the documentation of this file.
1 
21 #pragma once
22 #include "NodeRequestResult.h"
23 #include "PeerConnectCode.h"
24 #include "ServerConnector.h"
25 #include "catapult/ionet/Node.h"
27 #include "catapult/thread/Future.h"
31 
32 namespace catapult { namespace net {
33 
34  namespace detail {
37  public:
38  template<typename T>
39  constexpr bool isResponseCompatible(const ionet::Node&, const T&) const {
40  return true;
41  }
42  };
43  }
44 
47  template<typename TRequestPolicy, typename TResponseCompatibilityChecker = detail::AlwaysCompatibleResponseCompatibilityChecker>
48  class BriefServerRequestor : public std::enable_shared_from_this<BriefServerRequestor<TRequestPolicy, TResponseCompatibilityChecker>> {
49  public:
51  using ResponseType = typename TRequestPolicy::ResponseType;
52 
55 
56  private:
57  // region NodeRequest
58 
59  class NodeRequest {
60  public:
62  const ionet::Node& requestNode,
63  const std::shared_ptr<thread::IoThreadPool>& pPool,
64  const TResponseCompatibilityChecker& compatibilityChecker,
65  const CallbackType& callback)
66  : m_requestNode(requestNode)
67  , m_pPool(pPool)
68  , m_compatibilityChecker(compatibilityChecker)
69  , m_callback(callback)
70  {}
71 
72  public:
73  void setTimeout(const utils::TimeSpan& timeout, const std::shared_ptr<ionet::PacketSocket>& pSocket) {
74  auto pTimedCallback = thread::MakeTimedCallback(
75  m_pPool->ioContext(),
76  m_callback,
77  NodeRequestResult::Failure_Timeout,
78  ResponseType());
79  pTimedCallback->setTimeout(timeout);
80  pTimedCallback->setTimeoutHandler([pSocket, requestNode = m_requestNode]() {
81  pSocket->close();
82  CATAPULT_LOG(debug) << TRequestPolicy::Friendly_Name << " request connection to '" << requestNode << "' timed out";
83  });
84  m_callback = [pTimedCallback](auto result, const auto& response) {
85  pTimedCallback->callback(result, response);
86  };
87  }
88 
89  public:
90  void complete(PeerConnectCode connectCode) {
92  << TRequestPolicy::Friendly_Name << " request connection to '" << m_requestNode
93  << "' failed: " << connectCode;
94  complete(NodeRequestResult::Failure_Connection);
95  }
96 
97  void complete(thread::future<ResponseType>&& responseFuture) {
98  try {
99  const auto& response = responseFuture.get();
100  if (!m_compatibilityChecker.isResponseCompatible(m_requestNode, response))
101  return complete(NodeRequestResult::Failure_Incompatible);
102 
103  complete(response);
104  } catch (const catapult_runtime_error& e) {
106  << "exception thrown during " << TRequestPolicy::Friendly_Name << " request to '"
107  << m_requestNode << "': " << e.what();
108  complete(NodeRequestResult::Failure_Interaction);
109  }
110  }
111 
112  private:
114  m_callback(result, ResponseType());
115  }
116 
117  void complete(const ResponseType& response) {
118  m_callback(NodeRequestResult::Success, response);
119  }
120 
121  private:
123  std::shared_ptr<thread::IoThreadPool> m_pPool;
124  TResponseCompatibilityChecker m_compatibilityChecker;
126  };
127 
128  // endregion
129 
130  public:
134  const std::shared_ptr<thread::IoThreadPool>& pPool,
135  const crypto::KeyPair& keyPair,
136  const ConnectionSettings& settings,
137  const TResponseCompatibilityChecker& responseCompatibilityChecker)
138  : m_pPool(pPool)
139  , m_responseCompatibilityChecker(responseCompatibilityChecker)
140  , m_requestTimeout(settings.Timeout)
141  , m_pConnector(CreateServerConnector(pPool, keyPair, settings))
142  , m_numTotalRequests(0)
144  {}
145 
146  public:
148  size_t numActiveConnections() const {
149  return m_pConnector->numActiveConnections();
150  }
151 
153  size_t numTotalRequests() const {
154  return m_numTotalRequests;
155  }
156 
158  size_t numSuccessfulRequests() const {
160  }
161 
162  public:
164  void beginRequest(const ionet::Node& node, const CallbackType& callback) {
166  auto wrappedCallback = [pThis = this->shared_from_this(), callback](auto result, const auto& response) {
167  if (NodeRequestResult::Success == result)
168  ++pThis->m_numSuccessfulRequests;
169 
170  callback(result, response);
171  };
172 
173  auto pRequest = std::make_shared<NodeRequest>(node, m_pPool, m_responseCompatibilityChecker, wrappedCallback);
174  m_pConnector->connect(node, [pRequest, requestTimeout = m_requestTimeout](auto connectCode, const auto& pSocket) {
175  pRequest->setTimeout(requestTimeout, pSocket);
176 
177  if (PeerConnectCode::Accepted != connectCode)
178  return pRequest->complete(connectCode);
179 
180  TRequestPolicy::CreateFuture(*pSocket).then([pSocket, pRequest](auto&& responseFuture) {
181  pRequest->complete(std::move(responseFuture));
182  });
183  });
184  }
185 
187  void shutdown() {
188  m_pConnector->shutdown();
189  }
190 
191  private:
192  std::shared_ptr<thread::IoThreadPool> m_pPool;
193  TResponseCompatibilityChecker m_responseCompatibilityChecker;
195  std::shared_ptr<ServerConnector> m_pConnector;
196 
197  std::atomic<size_t> m_numTotalRequests;
198  std::atomic<size_t> m_numSuccessfulRequests;
199  };
200 
202  template<typename TRequestor, typename TResult = std::pair<NodeRequestResult, typename TRequestor::ResponseType>>
203  thread::future<TResult> BeginRequestFuture(TRequestor& requestor, const ionet::Node& node) {
204  auto pPromise = std::make_shared<thread::promise<TResult>>();
205 
206  requestor.beginRequest(node, [pPromise](auto result, const auto& response) {
207  pPromise->set_value(std::make_pair(result, response));
208  });
209 
210  return pPromise->get_future();
211  }
212 }}
catapult::net::BriefServerRequestor::NodeRequest::setTimeout
void setTimeout(const utils::TimeSpan &timeout, const std::shared_ptr< ionet::PacketSocket > &pSocket)
Definition: BriefServerRequestor.h:73
CATAPULT_LOG
#define CATAPULT_LOG(SEV)
Writes a log entry to the default logger with SEV severity.
Definition: Logging.h:340
catapult::net::BriefServerRequestor::NodeRequest
Definition: BriefServerRequestor.h:59
catapult::net::BriefServerRequestor::ResponseType
typename TRequestPolicy::ResponseType ResponseType
Remote node response type.
Definition: BriefServerRequestor.h:51
Parser.debug
def debug(*args)
Definition: Parser.py:46
catapult::net::ConnectionSettings
Settings used to configure connections.
Definition: ConnectionSettings.h:31
catapult::net::NodeRequestResult
NodeRequestResult
Enumeration of possible results of a ping operation.
Definition: NodeRequestResult.h:44
catapult::net::PeerConnectCode
PeerConnectCode
Enumeration of possible peer connection codes.
Definition: PeerConnectCode.h:44
catapult::net::detail::AlwaysCompatibleResponseCompatibilityChecker
A default compatibility checker that indicates all responses are compatible.
Definition: BriefServerRequestor.h:36
NodeRequestResult.h
colorPrint.warning
def warning(*args)
Definition: colorPrint.py:10
catapult::net::BriefServerRequestor::shutdown
void shutdown()
Shuts down all connections.
Definition: BriefServerRequestor.h:187
catapult::net::CreateServerConnector
std::shared_ptr< ServerConnector > CreateServerConnector(const std::shared_ptr< thread::IoThreadPool > &pPool, const crypto::KeyPair &keyPair, const ConnectionSettings &settings)
Creates a server connector for a server with a key pair of keyPair using pPool and configured with se...
Definition: ServerConnector.cpp:119
catapult::net::BriefServerRequestor::numActiveConnections
size_t numActiveConnections() const
Gets the number of active connections.
Definition: BriefServerRequestor.h:148
catapult::net::BriefServerRequestor::NodeRequest::m_compatibilityChecker
TResponseCompatibilityChecker m_compatibilityChecker
Definition: BriefServerRequestor.h:124
catapult::utils::TimeSpan
Represents a time duration.
Definition: TimeSpan.h:30
catapult::net::BriefServerRequestor::numTotalRequests
size_t numTotalRequests() const
Gets the number of total requests.
Definition: BriefServerRequestor.h:153
PeerConnectCode.h
catapult::net::BriefServerRequestor::m_numTotalRequests
std::atomic< size_t > m_numTotalRequests
Definition: BriefServerRequestor.h:197
catapult::net::BriefServerRequestor::NodeRequest::complete
void complete(NodeRequestResult result)
Definition: BriefServerRequestor.h:113
catapult::net::BriefServerRequestor
Definition: BriefServerRequestor.h:48
catapult::net::BriefServerRequestor::NodeRequest::complete
void complete(const ResponseType &response)
Definition: BriefServerRequestor.h:117
catapult::net::detail::AlwaysCompatibleResponseCompatibilityChecker::isResponseCompatible
constexpr bool isResponseCompatible(const ionet::Node &, const T &) const
Definition: BriefServerRequestor.h:39
Friendly_Name
static constexpr auto Friendly_Name
Definition: RemoteNodeApi.cpp:34
PacketSocket.h
catapult::net::BriefServerRequestor::NodeRequest::complete
void complete(PeerConnectCode connectCode)
Definition: BriefServerRequestor.h:90
catapult::thread::MakeTimedCallback
auto MakeTimedCallback(boost::asio::io_context &ioContext, TCallback callback, TCallbackArgs &&... timeoutArgs)
Definition: TimedCallback.h:170
catapult::crypto::KeyPair
Represents a pair of private key with associated public key.
Definition: KeyPair.h:33
HexFormatter.h
catapult::net::BriefServerRequestor::m_numSuccessfulRequests
std::atomic< size_t > m_numSuccessfulRequests
Definition: BriefServerRequestor.h:198
catapult::net::BriefServerRequestor::beginRequest
void beginRequest(const ionet::Node &node, const CallbackType &callback)
Initiates a request for data from node and calls callback on completion.
Definition: BriefServerRequestor.h:164
catapult::thread::future
Provides a way to access the result of an asynchronous operation.
Definition: Future.h:29
Node.h
IoThreadPool.h
catapult::net::BriefServerRequestor::m_requestTimeout
utils::TimeSpan m_requestTimeout
Definition: BriefServerRequestor.h:194
catapult::net::BriefServerRequestor::NodeRequest::complete
void complete(thread::future< ResponseType > &&responseFuture)
Definition: BriefServerRequestor.h:97
catapult::net::BriefServerRequestor::m_pPool
std::shared_ptr< thread::IoThreadPool > m_pPool
Definition: BriefServerRequestor.h:192
catapult::net::BriefServerRequestor::NodeRequest::m_requestNode
ionet::Node m_requestNode
Definition: BriefServerRequestor.h:122
catapult::net::BriefServerRequestor::NodeRequest::m_callback
CallbackType m_callback
Definition: BriefServerRequestor.h:125
catapult::net::BriefServerRequestor::NodeRequest::m_pPool
std::shared_ptr< thread::IoThreadPool > m_pPool
Definition: BriefServerRequestor.h:123
ServerConnector.h
catapult::net::BriefServerRequestor::m_responseCompatibilityChecker
TResponseCompatibilityChecker m_responseCompatibilityChecker
Definition: BriefServerRequestor.h:193
catapult::net::BriefServerRequestor::NodeRequest::NodeRequest
NodeRequest(const ionet::Node &requestNode, const std::shared_ptr< thread::IoThreadPool > &pPool, const TResponseCompatibilityChecker &compatibilityChecker, const CallbackType &callback)
Definition: BriefServerRequestor.h:61
pSocket
SocketPointer pSocket
Definition: PacketWriters.cpp:46
catapult
Definition: AddressExtractionExtension.cpp:28
catapult::net::BriefServerRequestor::BriefServerRequestor
BriefServerRequestor(const std::shared_ptr< thread::IoThreadPool > &pPool, const crypto::KeyPair &keyPair, const ConnectionSettings &settings, const TResponseCompatibilityChecker &responseCompatibilityChecker)
Definition: BriefServerRequestor.h:133
Future.h
catapult::catapult_error
Base class for all catapult exceptions that derives from both std::exception and boost::exception.
Definition: exceptions.h:42
catapult::net::BeginRequestFuture
thread::future< TResult > BeginRequestFuture(TRequestor &requestor, const ionet::Node &node)
Initiates a request for data from node using requestor and returns a future.
Definition: BriefServerRequestor.h:203
catapult::ionet::Node
A node in the catapult network.
Definition: Node.h:82
catapult::consumer
std::function< void(TArgs...)> consumer
A consumer function.
Definition: functions.h:35
catapult::net::BriefServerRequestor::CallbackType
consumer< NodeRequestResult, const ResponseType & > CallbackType
Request completion callback type.
Definition: BriefServerRequestor.h:54
catapult::net::BriefServerRequestor::numSuccessfulRequests
size_t numSuccessfulRequests() const
Gets the number of successful requests.
Definition: BriefServerRequestor.h:158
catapult::net::BriefServerRequestor::m_pConnector
std::shared_ptr< ServerConnector > m_pConnector
Definition: BriefServerRequestor.h:195
TimedCallback.h