| 271 | } |
| 272 | |
| 273 | void |
| 274 | NextHopConsistentHash::findNextHop(TSHttpTxn txnp, void * /* ih ATS_UNUSED */, time_t now) |
| 275 | { |
| 276 | uint32_t const NO_RING_USE_POST_REMAP = uint32_t(0) - 1; |
| 277 | |
| 278 | HttpSM *sm = reinterpret_cast<HttpSM *>(txnp); |
| 279 | ParentResult &result = sm->t_state.parent_result; |
| 280 | HttpRequestData &request_info = sm->t_state.request_data; |
| 281 | int64_t sm_id = sm->sm_id; |
| 282 | int64_t retry_time = sm->t_state.txn_conf->parent_retry_time; |
| 283 | time_t _now = now; |
| 284 | bool firstcall = false; |
| 285 | bool nextHopRetry = false; |
| 286 | bool wrapped = false; |
| 287 | std::vector<bool> wrap_around(groups, false); |
| 288 | uint32_t cur_ring = 0; // there is a hash ring for each host group |
| 289 | uint32_t lookups = 0; |
| 290 | std::shared_ptr<HostRecord> pRec = nullptr; |
| 291 | HostStatus &pStatus = HostStatus::instance(); |
| 292 | TSHostStatus host_stat = TSHostStatus::TS_HOST_STATUS_INIT; |
| 293 | HostStatRec *hst = nullptr; |
| 294 | Machine *machine = Machine::instance(); |
| 295 | std::string_view first_call_host; |
| 296 | int first_call_port = 0; |
| 297 | |
| 298 | if (result.line_number == -1 && result.result == PARENT_UNDEFINED) { |
| 299 | firstcall = true; |
| 300 | } |
| 301 | |
| 302 | // firstcall indicates that this is the first time the state machine has called findNextHop() for this |
| 303 | // particular transaction so, a parent will be looked up using a hash from the request to locate a |
| 304 | // parent on the consistent hash ring. If not first call, then the transaction was unable to use the parent |
| 305 | // returned from the "firstcall" due to some error so, subsequent calls will not search using a hash but, |
| 306 | // will instead just increment the hash table iterator to find the next parent on the ring |
| 307 | if (firstcall) { |
| 308 | NH_Dbg(NH_DBG_CTL, "[%" PRIu64 "] firstcall, line_number: %d, result: %s", sm_id, result.line_number, |
| 309 | ParentResultStr[result.result]); |
| 310 | result.line_number = distance; |
| 311 | cur_ring = 0; |
| 312 | for (uint32_t i = 0; i < groups; i++) { |
| 313 | result.chash_init[i] = false; |
| 314 | wrap_around[i] = false; |
| 315 | } |
| 316 | } else { |
| 317 | // not first call, save the previously tried parent. |
| 318 | if (result.hostname) { |
| 319 | first_call_host = result.hostname; |
| 320 | first_call_port = result.port; |
| 321 | } |
| 322 | NH_Dbg(NH_DBG_CTL, "[%" PRIu64 "] not firstcall, line_number: %d, result: %s", sm_id, result.line_number, |
| 323 | ParentResultStr[result.result]); |
| 324 | switch (ring_mode) { |
| 325 | case NH_ALTERNATE_RING: |
| 326 | if (groups > 1) { |
| 327 | cur_ring = (result.last_group + 1) % groups; |
| 328 | } else { |
| 329 | cur_ring = result.last_group; |
| 330 | } |