typename RouterInfo::RouteHandlePtr createEagerShardSelectionRoute()

in mcrouter/routes/ShardSelectionRouteFactory-inl.h [408:491]


typename RouterInfo::RouteHandlePtr createEagerShardSelectionRoute(
    RouteHandleFactory<typename RouterInfo::RouteHandleIf>& factory,
    const folly::dynamic& json,
    const ChildrenFactoryMap<RouterInfo>& childrenFactoryMap) {
  checkLogic(
      json.isObject(), "EagerShardSelectionRoute config should be an object");

  const auto childrenType = [&json]() {
    auto jChildType = json.get_ptr("children_type");
    checkLogic(
        jChildType && jChildType->isString(),
        "EagerShardSelectionRoute: 'children_type' not found or is not a "
        "string");
    return jChildType->stringPiece();
  }();

  const auto& childrenSettings = [&json]() {
    auto jSettings = json.get_ptr("children_settings");
    checkLogic(
        jSettings && jSettings->isObject(),
        "EagerShardSelectionRoute: 'children_settings' not found or not an "
        "object");
    return *jSettings;
  }();

  auto shardMap = detail::getShardDestinationsMap<RouterInfo>(factory, json);
  if (shardMap.empty()) {
    return mcrouter::createErrorRoute<RouterInfo>(
        "EagerShardSelectionRoute has an empty list of destinations");
  }

  MapType shardToDestinationIndexMap = detail::prepareMap<MapType>(
      shardMap.size(), detail::getMaxShardId(shardMap));
  std::vector<typename RouterInfo::RouteHandlePtr> destinations;
  if (childrenType == "LoadBalancerRoute") {
    detail::buildChildrenLoadBalancerRoutes<RouterInfo, MapType>(
        factory,
        childrenSettings,
        shardMap,
        destinations,
        shardToDestinationIndexMap);
  } else if (childrenType == "LatestRoute") {
    detail::buildChildrenLatestRoutes<RouterInfo, MapType>(
        factory,
        childrenSettings,
        shardMap,
        destinations,
        shardToDestinationIndexMap);
  } else if (childrenType == "CustomJsonmRoute") {
    detail::buildChildrenCustomJsonmRoutes<RouterInfo, MapType>(
        factory,
        childrenSettings,
        shardMap,
        destinations,
        shardToDestinationIndexMap);
  } else {
    auto it = childrenFactoryMap.find(childrenType.str());
    if (it != childrenFactoryMap.end()) {
      detail::buildChildrenCustomRoutesFromMap<RouterInfo, MapType>(
          factory,
          childrenSettings,
          shardMap,
          it->second,
          destinations,
          shardToDestinationIndexMap);
    } else {
      throwLogic(
          "EagerShardSelectionRoute: 'children_type' {} not supported",
          childrenType);
    }
  }

  ShardSelector selector(std::move(shardToDestinationIndexMap));

  typename RouterInfo::RouteHandlePtr outOfRangeDestination = nullptr;
  if (auto outOfRangeJson = json.get_ptr("out_of_range")) {
    outOfRangeDestination = factory.create(*outOfRangeJson);
  }

  return createSelectionRoute<RouterInfo, ShardSelector>(
      std::move(destinations),
      std::move(selector),
      std::move(outOfRangeDestination));
}