CatapultServer  v0.5.0.1 (Elephant)
RemoteRequestDispatcher.h
Go to the documentation of this file.
1 
21 #pragma once
22 #include "ApiTypes.h"
24 #include "catapult/thread/Future.h"
25 
26 namespace catapult { namespace api {
27 
30  public:
33  {}
34 
35  public:
37  template<typename TFuncTraits, typename... TArgs>
38  thread::future<typename TFuncTraits::ResultType> dispatch(const TFuncTraits& traits, TArgs&&... args) {
39  auto pPromise = std::make_shared<thread::promise<typename TFuncTraits::ResultType>>();
40  auto future = pPromise->get_future();
41  auto packetPayload = TFuncTraits::CreateRequestPacketPayload(std::forward<TArgs>(args)...);
42  send(traits, packetPayload, [pPromise](auto result, auto&& value) {
43  if (RemoteChainResult::Success == result) {
44  pPromise->set_value(std::move(value));
45  return;
46  }
47 
48  auto message = GetErrorMessage(result);
49  CATAPULT_LOG(error) << message << " for " << TFuncTraits::Friendly_Name << " request";
50  pPromise->set_exception(std::make_exception_ptr(catapult_api_error(message)));
51  });
52 
53  return future;
54  }
55 
56  private:
57  template<typename TFuncTraits, typename TCallback>
58  void send(const TFuncTraits& traits, const ionet::PacketPayload& packetPayload, const TCallback& callback) {
59  using ResultType = typename TFuncTraits::ResultType;
60  m_io.write(packetPayload, [traits, callback, &io = m_io](auto code) {
61  if (ionet::SocketOperationCode::Success != code)
62  return callback(RemoteChainResult::Write_Error, ResultType());
63 
64  io.read([traits, callback](auto readCode, const auto* pResponsePacket) {
65  if (ionet::SocketOperationCode::Success != readCode)
66  return callback(RemoteChainResult::Read_Error, ResultType());
67 
68  if (TFuncTraits::Packet_Type != pResponsePacket->Type) {
69  CATAPULT_LOG(warning)
70  << "received packet of type " << pResponsePacket->Type
71  << " but expected type " << TFuncTraits::Packet_Type;
72  return callback(RemoteChainResult::Malformed_Packet, ResultType());
73  }
74 
75  ResultType result;
76  if (!traits.tryParseResult(*pResponsePacket, result)) {
78  << "unable to parse " << pResponsePacket->Type
79  << " packet (size = " << pResponsePacket->Size << ")";
80  return callback(RemoteChainResult::Malformed_Packet, ResultType());
81  }
82 
83  return callback(RemoteChainResult::Success, std::move(result));
84  });
85  });
86  }
87 
88  private:
89  enum class RemoteChainResult {
90  Success,
92  Read_Error,
94  };
95 
96  static constexpr const char* GetErrorMessage(RemoteChainResult result) {
97  switch (result) {
99  return "write to remote node failed";
101  return "read from remote node failed";
102  default:
103  return "remote node returned malformed packet";
104  }
105  }
106 
107  private:
109  };
110 }}
CATAPULT_LOG
#define CATAPULT_LOG(SEV)
Writes a log entry to the default logger with SEV severity.
Definition: Logging.h:340
catapult::api::RemoteRequestDispatcher::GetErrorMessage
static constexpr const char * GetErrorMessage(RemoteChainResult result)
Definition: RemoteRequestDispatcher.h:96
colorPrint.warning
def warning(*args)
Definition: colorPrint.py:10
catapult::api::catapult_api_error
Exception class that is thrown when a catapult api operation produces an error.
Definition: ApiTypes.h:27
catapult::api::RemoteRequestDispatcher::RemoteChainResult::Read_Error
catapult::api::RemoteRequestDispatcher::RemoteRequestDispatcher
RemoteRequestDispatcher(ionet::PacketIo &io)
Creates a remote request dispatcher around io.
Definition: RemoteRequestDispatcher.h:32
Friendly_Name
static constexpr auto Friendly_Name
Definition: RemoteNodeApi.cpp:34
Packet_Type
static constexpr auto Packet_Type
Definition: RemoteNodeApi.cpp:33
catapult::ionet::PacketIo
An interface for reading and writing packets.
Definition: PacketIo.h:31
ApiTypes.h
catapult::thread::future
Provides a way to access the result of an asynchronous operation.
Definition: Future.h:29
catapult::api::RemoteRequestDispatcher::dispatch
thread::future< typename TFuncTraits::ResultType > dispatch(const TFuncTraits &traits, TArgs &&... args)
Dispatches args to the underlying io.
Definition: RemoteRequestDispatcher.h:38
catapult::api::RemoteRequestDispatcher::send
void send(const TFuncTraits &traits, const ionet::PacketPayload &packetPayload, const TCallback &callback)
Definition: RemoteRequestDispatcher.h:58
catapult::api::RemoteRequestDispatcher
Dispatches requests to a remote node.
Definition: RemoteRequestDispatcher.h:29
catapult::ionet::PacketIo::write
virtual void write(const PacketPayload &payload, const WriteCallback &callback)=0
Writes payload and calls callback on completion.
catapult::api::RemoteRequestDispatcher::RemoteChainResult
RemoteChainResult
Definition: RemoteRequestDispatcher.h:89
catapult::api::RemoteRequestDispatcher::RemoteChainResult::Write_Error
catapult::api::RemoteRequestDispatcher::RemoteChainResult::Success
catapult::api::RemoteRequestDispatcher::RemoteChainResult::Malformed_Packet
catapult::ionet::PacketPayload
A packet payload that can be written.
Definition: PacketPayload.h:29
catapult
Definition: AddressExtractionExtension.cpp:28
catapult::api::RemoteRequestDispatcher::m_io
ionet::PacketIo & m_io
Definition: RemoteRequestDispatcher.h:108
Future.h
PacketIo.h