| 61 | virtual ~MasterClient() {} |
| 62 | |
| 63 | RetCode ClientCall(Req &req, Resp &resp, |
| 64 | std::function<RetCode (Req &, Resp &)> rpc_func) { |
| 65 | RetCode ret = RetCode::RET_OK; |
| 66 | |
| 67 | auto &&route_key = GetRouteKeyByReq(req); |
| 68 | |
| 69 | proto::Addr master_addr; |
| 70 | if (!GetAddrFromCache(route_key, master_addr)) { |
| 71 | // no master cache, find one |
| 72 | QLVerb("no master cache. route_key(%s)", route_key.c_str()); |
| 73 | } else { |
| 74 | req.mutable_master_addr()->CopyFrom(master_addr); |
| 75 | ret = rpc_func(req, resp); |
| 76 | |
| 77 | QLVerb("rpc_func ret %d addr(%s:%d) route_key(%s)", as_integer(ret), master_addr.ip().c_str(), |
| 78 | master_addr.port(), route_key.c_str()); |
| 79 | |
| 80 | if (RetCode::RET_OK == ret) { |
| 81 | PutAddrToCache(route_key, master_addr); |
| 82 | return RetCode::RET_OK; |
| 83 | } else if (RetCode::RET_ERR_NOT_MASTER == ret && |
| 84 | !resp.redirect_addr().ip().empty() && |
| 85 | 0 != resp.redirect_addr().port()) { |
| 86 | // master change, update cache |
| 87 | PutAddrToCache(route_key, resp.redirect_addr()); |
| 88 | } else if (RetCode::RET_ERR_NOT_MASTER == ret || RetCode::RET_ERR_NO_MASTER == ret || |
| 89 | RetCode::RET_ERR_SVR_BLOCK == ret) { |
| 90 | // no master, remove cache and find one |
| 91 | RemoveCache(route_key); |
| 92 | } else if (RetCode::RET_ERR_SYS == ret) { |
| 93 | // sys err, not remove cache |
| 94 | } else { |
| 95 | QLErr("ClientCallByAddr ret %d addr(%s:%d) route_key(%s)", ret, |
| 96 | master_addr.ip().c_str(), master_addr.port(), route_key.c_str()); |
| 97 | return ret; |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | std::vector<proto::Addr> addrs; |
| 102 | { |
| 103 | RetCode ret1; |
| 104 | if (RetCode::RET_OK != (ret1 = GetCandidateAddrs(req, addrs))) { |
| 105 | QLErr("GetCandidateAddrs err %d route_key(%s)", ret1, route_key.c_str()); |
| 106 | return ret1; |
| 107 | } |
| 108 | } |
| 109 | if (!addrs.size()) { |
| 110 | QLErr("GetCandidateAddrs addr size 0"); |
| 111 | return RetCode::RET_ERR_LOGIC; |
| 112 | } |
| 113 | |
| 114 | int addrs_idx = 0; |
| 115 | proto::Addr addr; |
| 116 | if (RetCode::RET_ERR_NOT_MASTER == ret && GetAddrFromCache(route_key, addr)) { |
| 117 | for (int i{0}; i < addrs.size(); ++i) { |
| 118 | if (addr.ip() == addrs[i].ip() && addr.port() == addrs[i].port()) { |
| 119 | addrs_idx = i; |
| 120 | break; |
no test coverage detected