| 488 | |
| 489 | template <typename Op> |
| 490 | std::vector<Op *> selectRoutingTargetForOps(ClientRequestContext &requestCtx, |
| 491 | const std::shared_ptr<hf3fs::client::RoutingInfo const> &routingInfo, |
| 492 | const TargetSelectionOptions &options, |
| 493 | const std::vector<Op *> &ops) { |
| 494 | if (routingInfo == nullptr) { |
| 495 | XLOGF(ERR, "Unexpected: routing info is nullptr"); |
| 496 | setErrorCodeOfOps(ops, StorageClientCode::kRoutingError); |
| 497 | return {}; |
| 498 | } |
| 499 | |
| 500 | XLOGF_IF(INFO, |
| 501 | requestCtx.retryCount > 0, |
| 502 | "Start to select routing targets for {} {} ops {} based on {}: " |
| 503 | "bootstrapping? {}, {} nodes, {} chain tables, {} chains, {} targets", |
| 504 | ops.size(), |
| 505 | magic_enum::enum_name(requestCtx.methodType), |
| 506 | fmt::ptr(&ops), |
| 507 | routingInfo->raw()->routingInfoVersion, |
| 508 | routingInfo->raw()->bootstrapping, |
| 509 | routingInfo->raw()->nodes.size(), |
| 510 | routingInfo->raw()->chainTables.size(), |
| 511 | routingInfo->raw()->chains.size(), |
| 512 | routingInfo->raw()->targets.size()); |
| 513 | |
| 514 | std::unordered_map<ChainId, SlimChainInfo> slimChains(ops.size()); |
| 515 | std::unordered_map<ChainId, hf3fs::flat::ChainInfo> chainInfos(ops.size()); |
| 516 | auto targetSelectionStrategy = TargetSelectionStrategy::create(options); |
| 517 | auto selectNodeInTrafficZone = flat::selectNodeByTrafficZone(options.trafficZone()); |
| 518 | |
| 519 | std::vector<Op *> targetedOps; |
| 520 | targetedOps.reserve(ops.size()); |
| 521 | |
| 522 | for (auto op : ops) { |
| 523 | auto chainId = op->routingTarget.chainId; |
| 524 | |
| 525 | if (slimChains.count(chainId) == 0) { |
| 526 | auto chainInfo = getChainInfo(routingInfo, hf3fs::flat::ChainId(chainId)); |
| 527 | |
| 528 | if (!chainInfo) { |
| 529 | setErrorCodeOfOp(op, chainInfo.error().code()); |
| 530 | continue; |
| 531 | } |
| 532 | |
| 533 | chainInfos.emplace(chainId, *chainInfo); |
| 534 | |
| 535 | auto servingTargets = selectServingTargets(routingInfo, *chainInfo, selectNodeInTrafficZone); |
| 536 | |
| 537 | if (!servingTargets) { |
| 538 | setErrorCodeOfOp(op, servingTargets.error().code()); |
| 539 | continue; |
| 540 | } |
| 541 | |
| 542 | if (servingTargets->empty()) { |
| 543 | XLOGF(DBG3, |
| 544 | "All targets on the chain not serving or not in traffic zone ({}): {}", |
| 545 | options.trafficZone(), |
| 546 | *chainInfo); |
| 547 | } else if (targetSelectionStrategy->selectAnyTarget()) { |
no test coverage detected