| | |
| | | |
| | | namespace |
| | | { |
| | | inline void AddRoute(BHMsgHead &head, const MQId id) { head.add_route()->set_mq_id(id); } |
| | | inline void AddRoute(BHMsgHead &head, const ShmSocket &sock) |
| | | { |
| | | auto route = head.add_route(); |
| | | route->set_mq_id(sock.id()); |
| | | route->set_abs_addr(sock.AbsAddr()); |
| | | } |
| | | |
| | | struct SrcInfo { |
| | | std::vector<BHAddress> route; |
| | |
| | | } // namespace |
| | | |
| | | TopicNode::TopicNode(SharedMemory &shm) : |
| | | shm_(shm), state_(eStateUnregistered) |
| | | shm_(shm), state_(eStateUninited) |
| | | { |
| | | } |
| | | |
| | |
| | | auto end_time = steady_clock::now() + 3s; |
| | | do { |
| | | try { |
| | | //TODO recv offset, avoid query. |
| | | for (int i = eSockStart; i < eSockEnd; ++i) { |
| | | sockets_.emplace_back(new ShmSocket(shm_, false, ssn_id_ + i, kMqLen)); |
| | | } |
| | |
| | | NodeInit(); |
| | | } |
| | | if (!sockets_.empty()) { |
| | | LOG_DEBUG() << "node sockets ok"; |
| | | auto onNodeCmd = [this](ShmSocket &socket, int64_t &val) { |
| | | LOG_DEBUG() << "node recv cmd: " << DecodeCmd(val); |
| | | switch (DecodeCmd(val)) { |
| | |
| | | DEFER1(msg.Release()); |
| | | MsgProcInit body; |
| | | auto head = InitMsgHead(GetType(body), info_.proc_id(), ssn_id_); |
| | | head.add_route()->set_mq_id(ssn_id_); |
| | | AddRoute(head, socket); |
| | | if (msg.Fill(head, body)) { |
| | | socket.Send(BHTopicCenterAddress(), msg); |
| | | } |
| | |
| | | MsgProcInitReply reply; |
| | | if (imsg.ParseBody(reply)) { |
| | | SetProcIndex(reply.proc_index()); |
| | | this->state_ = eStateUnregistered; |
| | | } |
| | | } |
| | | return true; |
| | | }; |
| | | SockNode().Start(1, onMsg, onNodeCmd); |
| | | LOG_DEBUG() << "sockets ok."; |
| | | return true; |
| | | } |
| | | return false; |
| | |
| | | SetLastError(eError, kErrMsgNotInit); |
| | | return false; |
| | | } |
| | | auto end_time = steady_clock::now() + milliseconds(timeout_ms); |
| | | |
| | | while (state_ != eStateUnregistered && steady_clock::now() < end_time) { |
| | | std::this_thread::yield(); |
| | | } |
| | | if (state_ != eStateUnregistered) { |
| | | SetLastError(eError, kErrMsgNotInit); |
| | | return false; |
| | | } |
| | | |
| | | auto &sock = SockNode(); |
| | | MsgRegister body; |
| | | body.mutable_proc()->Swap(&proc); |
| | | auto AddId = [&](const MQId id) { body.add_addrs()->set_mq_id(id); }; |
| | | AddId(SockNode().id()); |
| | | AddId(SockServer().id()); |
| | | AddId(SockClient().id()); |
| | | AddId(SockSub().id()); |
| | | AddId(SockPub().id()); |
| | | |
| | | auto head(InitMsgHead(GetType(body), body.proc().proc_id(), ssn())); |
| | | AddRoute(head, sock.id()); |
| | | AddRoute(head, sock); |
| | | |
| | | auto CheckResult = [this](MsgI &msg, BHMsgHead &head, MsgCommonReply &rbody) { |
| | | bool ok = head.type() == kMsgTypeCommonReply && |
| | |
| | | body.mutable_proc()->Swap(&proc); |
| | | |
| | | auto head(InitMsgHead(GetType(body), body.proc().proc_id(), ssn())); |
| | | AddRoute(head, sock.id()); |
| | | AddRoute(head, sock); |
| | | |
| | | auto CheckResult = [this](MsgI &msg, BHMsgHead &head, MsgCommonReply &rbody) { |
| | | bool r = head.type() == kMsgTypeCommonReply && |
| | |
| | | body.mutable_proc()->Swap(&proc); |
| | | |
| | | auto head(InitMsgHead(GetType(body), body.proc().proc_id(), ssn())); |
| | | AddRoute(head, sock.id()); |
| | | AddRoute(head, sock); |
| | | |
| | | if (timeout_ms == 0) { |
| | | return sock.Send(BHTopicCenterAddress(), head, body); |
| | |
| | | auto &sock = SockNode(); |
| | | |
| | | BHMsgHead head(InitMsgHead(GetType(query), proc_id(), ssn())); |
| | | AddRoute(head, sock.id()); |
| | | AddRoute(head, sock); |
| | | |
| | | MsgI reply; |
| | | DEFER1(reply.Release()); |
| | |
| | | body.mutable_topics()->Swap(&topics); |
| | | |
| | | auto head(InitMsgHead(GetType(body), proc_id(), ssn())); |
| | | AddRoute(head, sock.id()); |
| | | AddRoute(head, sock); |
| | | |
| | | if (timeout_ms == 0) { |
| | | return sock.Send(BHTopicCenterAddress(), head, body); |
| | |
| | | for (int i = 0; i < head.route_size() - 1; ++i) { |
| | | reply_head.add_route()->Swap(head.mutable_route(i)); |
| | | } |
| | | auto remote = head.route().rbegin()->mq_id(); |
| | | MQInfo remote = {head.route().rbegin()->mq_id(), head.route().rbegin()->abs_addr()}; |
| | | sock.Send(remote, reply_head, reply_body); |
| | | } |
| | | }; |
| | |
| | | MsgRequestTopic req; |
| | | if (!imsg.ParseBody(req)) { return; } |
| | | |
| | | SrcInfo *p = new SrcInfo; |
| | | p->route.assign(head.route().begin(), head.route().end()); |
| | | p->msg_id = head.msg_id(); |
| | | acb(p, *head.mutable_proc_id(), req); |
| | | try { |
| | | SrcInfo *p = new SrcInfo; |
| | | if (!p) { |
| | | throw std::runtime_error("no memory."); |
| | | } |
| | | p->route.assign(head.route().begin(), head.route().end()); |
| | | p->msg_id = head.msg_id(); |
| | | acb(p, *head.mutable_proc_id(), req); |
| | | } catch (std::exception &e) { |
| | | LOG_ERROR() << "error server handle msg:" << e.what(); |
| | | } |
| | | }; |
| | | |
| | | auto &sock = SockServer(); |
| | |
| | | if (sock.SyncRecv(imsg, head, timeout_ms) && head.type() == kMsgTypeRequestTopic) { |
| | | if (imsg.ParseBody(request)) { |
| | | head.mutable_proc_id()->swap(proc_id); |
| | | SrcInfo *p = new SrcInfo; |
| | | p->route.assign(head.route().begin(), head.route().end()); |
| | | p->msg_id = head.msg_id(); |
| | | src_info = p; |
| | | return true; |
| | | try { |
| | | SrcInfo *p = new SrcInfo; |
| | | if (!p) { |
| | | throw std::runtime_error("no memory."); |
| | | } |
| | | p->route.assign(head.route().begin(), head.route().end()); |
| | | p->msg_id = head.msg_id(); |
| | | src_info = p; |
| | | return true; |
| | | } catch (std::exception &e) { |
| | | LOG_ERROR() << "error recv request: " << e.what(); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | |
| | | for (unsigned i = 0; i < p->route.size() - 1; ++i) { |
| | | head.add_route()->Swap(&p->route[i]); |
| | | } |
| | | return sock.Send(p->route.back().mq_id(), head, body); |
| | | MQInfo dest = {p->route.back().mq_id(), p->route.back().abs_addr()}; |
| | | return sock.Send(dest, head, body); |
| | | } |
| | | |
| | | bool TopicNode::ClientStartWorker(RequestResultCB const &cb, const int nworker) |
| | |
| | | |
| | | out_msg_id = msg_id; |
| | | |
| | | auto SendTo = [this, msg_id](const BHAddress &addr, const MsgRequestTopic &req, const RequestResultCB &cb) { |
| | | auto SendTo = [this, msg_id](const MQInfo &remote, const MsgRequestTopic &req, const RequestResultCB &cb) { |
| | | auto &sock = SockClient(); |
| | | BHMsgHead head(InitMsgHead(GetType(req), proc_id(), ssn(), msg_id)); |
| | | AddRoute(head, sock.id()); |
| | | AddRoute(head, sock); |
| | | head.set_topic(req.topic()); |
| | | |
| | | if (cb) { |
| | |
| | | } |
| | | } |
| | | }; |
| | | return sock.Send(addr.mq_id(), head, req, onRecv); |
| | | return sock.Send(remote, head, req, onRecv); |
| | | } else { |
| | | return sock.Send(addr.mq_id(), head, req); |
| | | return sock.Send(remote, head, req); |
| | | } |
| | | }; |
| | | |
| | | try { |
| | | BHAddress addr; |
| | | return (ClientQueryRPCTopic(req.topic(), addr, 3000)) && SendTo(addr, req, cb); |
| | | return (ClientQueryRPCTopic(req.topic(), addr, 3000)) && SendTo(MQInfo{addr.mq_id(), addr.abs_addr()}, req, cb); |
| | | } catch (...) { |
| | | SetLastError(eError, "internal error."); |
| | | return false; |
| | |
| | | if (ClientQueryRPCTopic(request.topic(), addr, timeout_ms)) { |
| | | LOG_TRACE() << "node: " << SockNode().id() << ", topic dest: " << addr.mq_id(); |
| | | BHMsgHead head(InitMsgHead(GetType(request), proc_id(), ssn())); |
| | | AddRoute(head, sock.id()); |
| | | AddRoute(head, sock); |
| | | head.set_topic(request.topic()); |
| | | |
| | | MsgI reply_msg; |
| | | DEFER1(reply_msg.Release();); |
| | | BHMsgHead reply_head; |
| | | |
| | | if (sock.SendAndRecv(addr.mq_id(), head, request, reply_msg, reply_head, timeout_ms) && |
| | | if (sock.SendAndRecv({addr.mq_id(), addr.abs_addr()}, head, request, reply_msg, reply_head, timeout_ms) && |
| | | reply_head.type() == kMsgTypeRequestTopicReply && |
| | | reply_msg.ParseBody(out_reply)) { |
| | | reply_head.mutable_proc_id()->swap(out_proc_id); |
| | |
| | | return false; |
| | | } |
| | | |
| | | int TopicNode::QueryRPCTopics(const Topic &topic, std::vector<NodeAddress> &addr, const int timeout_ms) |
| | | int TopicNode::QueryTopicServers(const Topic &topic, std::vector<NodeAddress> &addr, const int timeout_ms) |
| | | { |
| | | int n = 0; |
| | | MsgQueryTopic query; |
| | |
| | | return true; |
| | | } |
| | | std::vector<NodeAddress> lst; |
| | | if (QueryRPCTopics(topic, lst, timeout_ms)) { |
| | | if (QueryTopicServers(topic, lst, timeout_ms)) { |
| | | addr = lst.front().addr(); |
| | | if (addr.mq_id() != 0) { |
| | | topic_query_cache_.Store(topic, addr); |
| | |
| | | try { |
| | | auto &sock = SockPub(); |
| | | BHMsgHead head(InitMsgHead(GetType(pub), proc_id(), ssn())); |
| | | AddRoute(head, sock.id()); |
| | | AddRoute(head, sock); |
| | | |
| | | if (timeout_ms == 0) { |
| | | return sock.Send(BHTopicBusAddress(), head, pub); |
| | |
| | | sub.mutable_topics()->Swap(&topics); |
| | | |
| | | BHMsgHead head(InitMsgHead(GetType(sub), proc_id(), ssn())); |
| | | AddRoute(head, sock.id()); |
| | | AddRoute(head, sock); |
| | | if (timeout_ms == 0) { |
| | | return sock.Send(BHTopicBusAddress(), head, sub); |
| | | } else { |