| 127 | } |
| 128 | |
| 129 | std::pair<int, std::string> fetchBlockServices(const std::string& addr, uint16_t port, Duration timeout, ShardId shid, std::vector<FullBlockServiceInfo>& blockServices, std::vector<BlockServiceInfoShort>& currentBlockServices) { |
| 130 | blockServices.clear(); |
| 131 | currentBlockServices.clear(); |
| 132 | |
| 133 | #define FAIL(err, errStr) do { blockServices.clear(); currentBlockServices.clear(); return {err, errStr}; } while (0) |
| 134 | |
| 135 | auto [sock, err] = registrySock(addr, port, timeout); |
| 136 | if (sock.error()) { |
| 137 | return {sock.getErrno(), err}; |
| 138 | } |
| 139 | |
| 140 | // all block services |
| 141 | { |
| 142 | RegistryReqContainer reqContainer; |
| 143 | auto& req = reqContainer.setAllBlockServices(); |
| 144 | { |
| 145 | const auto [err, errStr] = writeRegistryRequest(sock.get(), reqContainer, timeout); |
| 146 | if (err) { FAIL(err, errStr); } |
| 147 | } |
| 148 | |
| 149 | RegistryRespContainer respContainer; |
| 150 | { |
| 151 | const auto [err, errStr] = readRegistryResponse(sock.get(), respContainer, timeout); |
| 152 | if (err) { FAIL(err, errStr); } |
| 153 | } |
| 154 | |
| 155 | blockServices = respContainer.getAllBlockServices().blockServices.els; |
| 156 | } |
| 157 | |
| 158 | // current block services |
| 159 | { |
| 160 | RegistryReqContainer reqContainer; |
| 161 | auto& req = reqContainer.setShardBlockServices(); |
| 162 | req.shardId = shid; |
| 163 | { |
| 164 | const auto [err, errStr] = writeRegistryRequest(sock.get(), reqContainer, timeout); |
| 165 | if (err) { FAIL(err, errStr); } |
| 166 | } |
| 167 | |
| 168 | RegistryRespContainer respContainer; |
| 169 | { |
| 170 | const auto [err, errStr] = readRegistryResponse(sock.get(), respContainer, timeout); |
| 171 | if (err) { FAIL(err, errStr); } |
| 172 | } |
| 173 | |
| 174 | currentBlockServices = respContainer.getShardBlockServices().blockServices.els; |
| 175 | } |
| 176 | |
| 177 | // check that all current block services are known -- there's a small race here |
| 178 | // the caller should just retry in these cases. |
| 179 | // check that all current block services are from different failure domains |
| 180 | // registry should guarantee that when sending response but verify the invariant |
| 181 | { |
| 182 | std::unordered_set<uint64_t> knownBlockServices; |
| 183 | std::unordered_map<uint64_t, const FullBlockServiceInfo* > bsIdToBlockService; |
| 184 | std::unordered_set<std::string> fdSet; |
| 185 | for (const auto& bs : blockServices) { |
| 186 | knownBlockServices.insert(bs.id.u64); |
no test coverage detected