hmbdc
simplify-high-performance-messaging-programming
RecvTransportEngine.hpp
1 #include "hmbdc/Copyright.hpp"
2 #pragma once
3 #include "hmbdc/tips/rnetmap/Transport.hpp"
4 #include "hmbdc/tips/rnetmap/NmRecvTransport.hpp"
5 #include "hmbdc/tips/rnetmap/BackupRecvSession.hpp"
6 #include "hmbdc/tips/rnetmap/DefaultUserConfig.hpp"
7 #include "hmbdc/tips/reliable/AttBufferAdaptor.hpp"
8 #include "hmbdc/app/Logger.hpp"
9 #include "hmbdc/comm/inet/Hash.hpp"
10 
11 #include <boost/bind.hpp>
12 #include <boost/lexical_cast.hpp>
13 #include <boost/unordered_map.hpp>
14 
15 #include <memory>
16 #include <regex>
17 #include <type_traits>
18 #include <mutex>
19 
20 namespace hmbdc { namespace tips { namespace rnetmap {
24  , cfg.resetSection("rx", false)))
25  {}
26  virtual ~RecvTransport(){}
27 
28 };
29 
30 namespace recvtransportengine_detail {
31 
32 template <typename OutputBuffer, typename AttachmentAllocator>
37  friend struct NetContext; //only be created by NetContext
39  , OutputBuffer& outputBuffer)
40  : RecvTransport(cfgIn)
41  , cmdBuffer_(std::max({sizeof(app::MessageWrap<TypeTagBackupSource>)})
42  , config_.getExt<uint16_t>("cmdBufferSizePower2"))
43  , outputBuffer_(outputBuffer)
44  , myBackupIp_(inet_addr(hmbdc::comm::inet::getLocalIpMatchMask(
45  config_.getExt<std::string>("tcpIfaceAddr") == std::string("ifaceAddr")
46  ?config_.getExt<std::string>("ifaceAddr"):config_.getExt<std::string>("tcpIfaceAddr")
47  ).c_str()))
48  , nmRecvTransport_(config_
49  , cmdBuffer_ //to store cmds
50  , subscriptions_
51  , ep2SessionDict_)
52  , loopback_(config_.getExt<bool>("loopback")) {
53  subscriptions_.addAll<std::tuple<app::StartMemorySegTrain, app::MemorySeg>>();
54  if (!config_.getExt<bool>("allowRecvWithinProcess")) {
55  myPid_ = getpid();
56  }
57  }
58 
59  void runOnce() HMBDC_RESTRICT {
60  hmbdc::app::utils::EpollTask::instance().poll();
62  auto n = cmdBuffer_.peek(begin, end);
63  auto it = begin;
64  while (it != end) {
65  MD()(*this, *static_cast<app::MessageHead*>(*it++));
66  }
67  cmdBuffer_.wasteAfterPeek(begin, n);
68  nmRecvTransport_.runOnce();
69  for (auto it = recvSessions_.begin(); it != recvSessions_.end();) {
70  if (hmbdc_unlikely(!it->second->runOnce())) {
71  it->second->stop();
72  cancel(*it->second);
73  ep2SessionDict_.erase(it->second->sendFrom);
74  recvSessions_.erase(it++);
75  } else {
76  it++;
77  }
78  }
79  }
80 
81 /**
82  * @brief only used by MD
83  */
85  auto ip = inet_addr(t.ip);
86  //unless using loopback address, don't EVER listen to myself (own process)
87  if (ip == myBackupIp_
88  && (!loopback_)) {
89  return;
90  }
91  if (t.srcPid == myPid_ && ip == myBackupIp_) return;
92  auto key = std::make_pair(ip, t.port);
93  if (recvSessions_.find(key) == recvSessions_.end()) {
94  for (auto i = 0u; i < t.typeTagCountContained; ++i) {
95  if (subscriptions_.check(t.typeTags[i])) {
96  try {
97  typename Session::ptr sess {
98  new Session(
99  config_
100  , t.sendFrom
101  , subscriptions_
102  , outputBuffer_
103  , t.recvReportDelay
104  )
105  };
106  sess->start(ip, t.port);
107  recvSessions_[key] = sess;
108  ep2SessionDict_[t.sendFrom] = sess;
109  schedule(hmbdc::time::SysTime::now(), *sess);
110  } catch (std::exception const& e) {
111  HMBDC_LOG_C(e.what());
112  }
113  break;
114  }
115  }
116  } //else ignore
117  }
118 
119  /**
120  * @brief check how many other parties are sending to this engine
121  * @return recipient session count are still active
122  */
123  size_t sessionsRemainingActive() const {
124  return recvSessions_.size();
125  }
126 
127  template <MessageTupleC Messages, typename CcNode>
128  void subscribeFor(CcNode const& node, uint16_t mod, uint16_t res) {
129  subscriptions_.markSubsFor<Messages>(node, mod, res);
130  }
131 
132 private:
134 
135  pattern::MonoLockFreeBuffer cmdBuffer_;
136  OutputBuffer& outputBuffer_;
137  TypeTagSet subscriptions_;
138  uint64_t myBackupIp_;
139  using Ep2SessionDict //sender's ip address port ->
140  = boost::unordered_map<uint32_t, typename Session::ptr>;
141  Ep2SessionDict ep2SessionDict_;
142  boost::unordered_map<std::pair<uint64_t, uint16_t>
143  , typename Session::ptr> recvSessions_;
145  bool loopback_;
146  uint32_t myPid_ = 0;
147 };
148 
149 template <typename OutputBuffer, typename AttachmentAllocator>
151 : RecvTransportImpl<OutputBuffer, AttachmentAllocator>
152 , hmbdc::app::Client<RecvTransportEngine<OutputBuffer, AttachmentAllocator>> {
154  using Impl::Impl;
155 
156  void rotate() {
157  this->checkTimers(hmbdc::time::SysTime::now());
159  }
160 
161  /*virtual*/
162  void invokedCb(size_t) HMBDC_RESTRICT override {
163  Impl::runOnce();
164  }
165 
166  /*virtual*/
167  void stoppedCb(std::exception const& e) override {
168  HMBDC_LOG_C(e.what());
169  };
170 
171  using EngineTransport::hmbdcName;
172 
173  std::tuple<char const*, int> schedSpec() const {
174  return std::make_tuple(this->schedPolicy_.c_str(), this->schedPriority_);
175  }
176 };
177 } //recvtransportengine_detail
178 
179 template <typename OutputBuffer, typename AttachmentAllocator>
180 using RecvTransportEngine = recvtransportengine_detail::RecvTransportEngine<
181  OutputBuffer, AttachmentAllocator>;
182 }}}
T getExt(const path_type &param, bool throwIfMissing=true) const
get a value from the config
Definition: Config.hpp:238
Definition: MonoLockFreeBuffer.hpp:16
class to hold an hmbdc configuration
Definition: Config.hpp:44
void setAdditionalFallbackConfig(Config const &c)
set additional defaults
Definition: Config.hpp:153
Definition: Timers.hpp:70
Config & resetSection(char const *section, bool sectionExists=true)
change section name
Definition: Config.hpp:176
impl class
Definition: NmRecvTransport.hpp:25
void stoppedCb(std::exception const &e) override
callback called when this Client is taken out of message dispatching
Definition: RecvTransportEngine.hpp:167
void handleMessageCb(TypeTagBackupSource const &t)
only used by MD
Definition: RecvTransportEngine.hpp:84
Definition: MessageDispacher.hpp:184
Definition: Message.hpp:212
Definition: Messages.hpp:116
void invokedCb(size_t) HMBDC_RESTRICT override
this callback is called all the time (frequently) - the exact timing is after a batch of messages are...
Definition: RecvTransportEngine.hpp:162
void cancel(Timer &timer)
cancel a timer previously scheduled with the TimerManager
Definition: Timers.hpp:90
void schedule(SysTime fireAt, Timer &timer)
schedule the timer to start at a specific time
Definition: Timers.hpp:79
Definition: TypeTagSet.hpp:138
Definition: Message.hpp:263
Definition: RecvTransportEngine.hpp:21
A Client represents a thread of execution/a task. The execution is managed by a Context. a Client object could participate in message dispatching as the receiver of specifed message types.
Definition: Client.hpp:128
size_t sessionsRemainingActive() const
check how many other parties are sending to this engine
Definition: RecvTransportEngine.hpp:123
Definition: Base.hpp:12
void wasteAfterPeek(iterator, size_t, bool=false)
if size not matching - please refer to the impl for details
Definition: MonoLockFreeBuffer.hpp:160
Definition: LockFreeBufferMisc.hpp:89