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));
}