lichao
2021-05-06 0117d5f8ff386075b0c4cbec0cbe460fe3cfa680
src/topic_node.cpp
@@ -37,29 +37,52 @@
} // namespace
TopicNode::TopicNode(SharedMemory &shm) :
    shm_(shm), sockets_(eSockEnd), state_(eStateUnregistered)
    shm_(shm), state_(eStateUnregistered)
{
   for (int i = eSockStart; i < eSockEnd; ++i) {
      sockets_[i].reset(new ShmSocket(shm_, kMqLen));
   }
   // recv msgs to avoid memory leak.
   auto default_ignore_msg = [](ShmSocket &sock, MsgI &imsg, BHMsgHead &head) { return true; };
   for (auto &p : sockets_) {
      p->Start(default_ignore_msg);
   }
   Init();
}
TopicNode::~TopicNode()
{
   LOG_DEBUG() << "~TopicNode()";
   Stop();
   SockNode().Stop();
   if (state() == eStateUnregistered) {
      for (auto &p : sockets_) { p->Remove(); }
}
bool TopicNode::Init()
{
   std::lock_guard<std::mutex> lk(mutex_);
   if (Valid()) {
      return true;
   }
   if (ssn_id_ == 0) {
      ssn_id_ = ShmMsgQueue::NewId();
   }
   LOG_DEBUG() << "Node Init, id " << ssn_id_;
   MsgI msg;
   msg.OffsetRef() = ssn_id_;
   if (ShmMsgQueue::TrySend(shm(), BHInitAddress(), msg)) {
      sockets_.resize(eSockEnd);
      for (int i = eSockStart; i < eSockEnd; ++i) {
         sockets_[i].reset(new ShmSocket(shm_, ssn_id_ + i, kMqLen));
      }
      // recv msgs to avoid memory leak.
      auto default_ignore_msg = [](ShmSocket &sock, MsgI &imsg, BHMsgHead &head) { return true; };
      SockNode().Start(default_ignore_msg);
      return true;
   }
   return false;
}
void TopicNode::Start(ServerAsyncCB const &server_cb, SubDataCB const &sub_cb, RequestResultCB &client_cb, int nworker)
{
   std::lock_guard<std::mutex> lk(mutex_);
   if (!Init()) {
      SetLastError(eError, "BHome Node Not Inited.");
      return;
   }
   if (nworker < 1) {
      nworker = 1;
   } else if (nworker > 16) {
@@ -72,11 +95,18 @@
}
void TopicNode::Stop()
{
   LOG_DEBUG() << "Node Stopping";
   for (auto &p : sockets_) { p->Stop(); }
   LOG_INFO() << "Node Stopped";
}
bool TopicNode::Register(ProcInfo &proc, MsgCommonReply &reply_body, const int timeout_ms)
{
   if (!Init()) {
      SetLastError(eError, "BHome Node Not Inited.");
      return false;
   }
   info_ = proc;
   auto &sock = SockNode();
@@ -89,7 +119,7 @@
   AddId(SockSub().id());
   AddId(SockPub().id());
   auto head(InitMsgHead(GetType(body), body.proc().proc_id()));
   auto head(InitMsgHead(GetType(body), body.proc().proc_id(), ssn()));
   AddRoute(head, sock.id());
   auto CheckResult = [this](MsgI &msg, BHMsgHead &head, MsgCommonReply &rbody) {
@@ -122,6 +152,11 @@
}
bool TopicNode::Unregister(ProcInfo &proc, MsgCommonReply &reply_body, const int timeout_ms)
{
   if (!IsOnline()) {
      SetLastError(eNotRegistered, "Not Registered.");
      return false;
   }
   info_.Clear();
   state_cas(eStateOnline, eStateOffline);
@@ -129,7 +164,7 @@
   MsgUnregister body;
   body.mutable_proc()->Swap(&proc);
   auto head(InitMsgHead(GetType(body), body.proc().proc_id()));
   auto head(InitMsgHead(GetType(body), body.proc().proc_id(), ssn()));
   AddRoute(head, sock.id());
   auto CheckResult = [this](MsgI &msg, BHMsgHead &head, MsgCommonReply &rbody) {
@@ -165,7 +200,7 @@
   MsgHeartbeat body;
   body.mutable_proc()->Swap(&proc);
   auto head(InitMsgHead(GetType(body), body.proc().proc_id()));
   auto head(InitMsgHead(GetType(body), body.proc().proc_id(), ssn()));
   AddRoute(head, sock.id());
   if (timeout_ms == 0) {
@@ -195,7 +230,7 @@
   }
   auto &sock = SockNode();
   BHMsgHead head(InitMsgHead(GetType(query), proc_id()));
   BHMsgHead head(InitMsgHead(GetType(query), proc_id(), ssn()));
   AddRoute(head, sock.id());
   MsgI reply;
@@ -217,7 +252,7 @@
   MsgRegisterRPC body;
   body.mutable_topics()->Swap(&topics);
   auto head(InitMsgHead(GetType(body), proc_id()));
   auto head(InitMsgHead(GetType(body), proc_id(), ssn()));
   AddRoute(head, sock.id());
   if (timeout_ms == 0) {
@@ -242,7 +277,7 @@
      MsgRequestTopicReply reply_body;
      if (rcb(head.proc_id(), req, reply_body)) {
         BHMsgHead reply_head(InitMsgHead(GetType(reply_body), proc_id(), head.msg_id()));
         BHMsgHead reply_head(InitMsgHead(GetType(reply_body), proc_id(), ssn(), head.msg_id()));
         for (int i = 0; i < head.route_size() - 1; ++i) {
            reply_head.add_route()->Swap(head.mutable_route(i));
@@ -311,7 +346,7 @@
   if (!p || p->route.empty()) {
      return false;
   }
   BHMsgHead head(InitMsgHead(GetType(body), proc_id(), p->msg_id));
   BHMsgHead head(InitMsgHead(GetType(body), proc_id(), ssn(), p->msg_id));
   for (unsigned i = 0; i < p->route.size() - 1; ++i) {
      head.add_route()->Swap(&p->route[i]);
   }
@@ -348,7 +383,7 @@
   auto SendTo = [this, msg_id](const BHAddress &addr, const MsgRequestTopic &req, const RequestResultCB &cb) {
      auto &sock = SockClient();
      BHMsgHead head(InitMsgHead(GetType(req), proc_id(), msg_id));
      BHMsgHead head(InitMsgHead(GetType(req), proc_id(), ssn(), msg_id));
      AddRoute(head, sock.id());
      head.set_topic(req.topic());
@@ -388,7 +423,8 @@
      BHAddress addr;
      if (ClientQueryRPCTopic(request.topic(), addr, timeout_ms)) {
         BHMsgHead head(InitMsgHead(GetType(request), proc_id()));
         LOG_TRACE() << "node: " << SockNode().id() << ", topic dest: " << addr.mq_id();
         BHMsgHead head(InitMsgHead(GetType(request), proc_id(), ssn()));
         AddRoute(head, sock.id());
         head.set_topic(request.topic());
@@ -402,8 +438,6 @@
            reply_head.mutable_proc_id()->swap(out_proc_id);
            return true;
         }
      } else {
         SetLastError(eNotFound, "remote not found.");
      }
   } catch (...) {
      SetLastError(eError, __func__ + std::string(" internal errer."));
@@ -446,6 +480,7 @@
         return true;
      }
   }
   SetLastError(eNotFound, "remote not found.");
   return false;
}
@@ -460,7 +495,7 @@
   try {
      auto &sock = SockPub();
      BHMsgHead head(InitMsgHead(GetType(pub), proc_id()));
      BHMsgHead head(InitMsgHead(GetType(pub), proc_id(), ssn()));
      AddRoute(head, sock.id());
      if (timeout_ms == 0) {
@@ -494,7 +529,7 @@
      MsgSubscribe sub;
      sub.mutable_topics()->Swap(&topics);
      BHMsgHead head(InitMsgHead(GetType(sub), proc_id()));
      BHMsgHead head(InitMsgHead(GetType(sub), proc_id(), ssn()));
      AddRoute(head, sock.id());
      if (timeout_ms == 0) {
         return sock.Send(BHTopicBusAddress(), head, sub);