Exemplo n.º 1
0
McRouteHandleProvider::McRouteHandleProvider(
  proxy_t* proxy,
  ProxyDestinationMap& destinationMap,
  PoolFactory& poolFactory)
    : proxy_(proxy),
      destinationMap_(destinationMap),
      poolFactory_(poolFactory),
      extraProvider_(createExtraRouteHandleProvider()),
      routeMap_{
        { "AllAsyncRoute", &makeAllAsyncRoute },
        { "AllFastestRoute", &makeAllFastestRoute },
        { "AllInitialRoute", &makeAllInitialRoute },
        { "AllMajorityRoute", &makeAllMajorityRoute },
        { "AllSyncRoute", &makeAllSyncRoute },
        {
          "AsynclogRoute",
          [](McRouteHandleFactory& factory, const folly::dynamic& json) {
            return makeAsynclogRoute(factory, json);
          }
        },
        { "DevNullRoute", &makeDevNullRoute },
        { "ErrorRoute", &makeErrorRoute },
        { "FailoverRoute", &makeFailoverRoute },
        { "FailoverWithExptimeRoute", &makeFailoverWithExptimeRoute },
        {
          "HashRoute",
          [](McRouteHandleFactory& factory, const folly::dynamic& json) {
            return makeHashRoute(factory, json);
          }
        },
        { "HostIdRoute", &makeHostIdRoute },
        { "L1L2CacheRoute", &makeL1L2CacheRoute },
        { "LatestRoute", &makeLatestRoute },
        { "LoggingRoute", &makeLoggingRoute },
        { "MigrateRoute", &makeMigrateRoute },
        { "MissFailoverRoute", &makeMissFailoverRoute },
        { "ModifyExptimeRoute", &makeModifyExptimeRoute },
        { "ModifyKeyRoute", &makeModifyKeyRoute },
        { "NullRoute", &makeNullRoute },
        { "OperationSelectorRoute", &makeOperationSelectorRoute },
        {
          "PoolRoute",
          [this](McRouteHandleFactory& factory, const folly::dynamic& json) {
            return makePoolRoute(factory, json);
          }
        },
        { "PrefixPolicyRoute", &makeOperationSelectorRoute },
        { "RandomRoute", &makeRandomRoute },
        {
          "RateLimitRoute",
          [](McRouteHandleFactory& factory, const folly::dynamic& json) {
            return makeRateLimitRoute(factory, json);
          }
        },
        { "WarmUpRoute", &makeWarmUpRoute },
      } {
}
Exemplo n.º 2
0
McrouterRouteHandlePtr makeRateLimitRoute(
    RouteHandleFactory<McrouterRouteHandleIf>& factory,
    const folly::dynamic& json) {
  checkLogic(json.isObject(), "RateLimitRoute is not an object");
  auto jtarget = json.get_ptr("target");
  checkLogic(jtarget, "RateLimitRoute: target not found");
  auto target = factory.create(*jtarget);
  auto jrates = json.get_ptr("rates");
  checkLogic(jrates, "RateLimitRoute: rates not found");
  return makeRateLimitRoute(std::move(target), RateLimiter(*jrates));
}
Exemplo n.º 3
0
McrouterRouteHandlePtr McRouteHandleProvider::makePoolRoute(
  McRouteHandleFactory& factory, const folly::dynamic& json) {

  checkLogic(json.isObject() || json.isString(),
             "PoolRoute should be object or string");
  const folly::dynamic* jpool;
  if (json.isObject()) {
    jpool = json.get_ptr("pool");
    checkLogic(jpool, "PoolRoute: pool not found");
  } else {
    jpool = &json;
  }
  auto p = makePool(*jpool);
  auto pool = std::move(p.first);
  auto destinations = std::move(p.second);

  if (json.isObject()) {
    if (auto maxOutstandingPtr = json.get_ptr("max_outstanding")) {
      checkLogic(maxOutstandingPtr->isInt(),
                 "PoolRoute {}: max_outstanding is not int", pool->getName());
      auto maxOutstanding = maxOutstandingPtr->asInt();
      if (maxOutstanding) {
        for (auto& destination: destinations) {
          destination = makeOutstandingLimitRoute(std::move(destination),
                                                  maxOutstanding);
        }
      }
    }
  }

  if (json.isObject() && json.count("shadows")) {
    folly::StringPiece shadowPolicy = "default";
    if (auto jshadow_policy = json.get_ptr("shadow_policy")) {
      checkLogic(jshadow_policy->isString(),
                 "PoolRoute: shadow_policy is not a string");
      shadowPolicy = jshadow_policy->stringPiece();
    }

    McrouterShadowData data;
    for (auto& shadow : json["shadows"]) {
      checkLogic(shadow.count("target"),
                 "PoolRoute {} shadows: no target for shadow", pool->getName());
      auto s = ShadowSettings::create(shadow, proxy_->router());
      if (s) {
        data.emplace_back(factory.create(shadow["target"]), std::move(s));
      }
    }

    for (size_t i = 0; i < destinations.size(); ++i) {
      McrouterShadowData destinationShadows;
      for (const auto& shadowData : data) {
        if (shadowData.second->startIndex() <= i &&
            i < shadowData.second->endIndex()) {
          destinationShadows.push_back(shadowData);
        }
      }
      if (!destinationShadows.empty()) {
        destinationShadows.shrink_to_fit();
        destinations[i] = extraProvider_->makeShadow(
          proxy_, std::move(destinations[i]),
          std::move(destinationShadows), shadowPolicy);
      }
    }
  }

  // add weights and override whatever we have in PoolRoute::hash
  folly::dynamic jhashWithWeights = folly::dynamic::object();
  if (pool->getWeights()) {
    jhashWithWeights = folly::dynamic::object
      ("hash_func", WeightedCh3HashFunc::type())
      ("weights", *pool->getWeights());
  }

  if (json.isObject()) {
    if (auto jhash = json.get_ptr("hash")) {
      checkLogic(jhash->isObject() || jhash->isString(),
                 "PoolRoute {}: hash is not object/string", pool->getName());
      if (jhash->isString()) {
        jhashWithWeights["hash_func"] = *jhash;
      } else { // object
        for (const auto& it : jhash->items()) {
          jhashWithWeights[it.first] = it.second;
        }
      }
    }
  }
  auto route = makeHashRoute(jhashWithWeights, std::move(destinations));

  if (json.isObject()) {
    if (proxy_->router().opts().destination_rate_limiting) {
      if (auto jrates = json.get_ptr("rates")) {
        route = makeRateLimitRoute(std::move(route), RateLimiter(*jrates));
      }
    }

    if (auto jsplits = json.get_ptr("shard_splits")) {
      route = makeShardSplitRoute(std::move(route), ShardSplitter(*jsplits));
    }
  }

  auto asynclogName = pool->getName();
  bool needAsynclog = true;
  if (json.isObject()) {
    if (auto jasynclog = json.get_ptr("asynclog")) {
      checkLogic(jasynclog->isBool(), "PoolRoute: asynclog is not bool");
      needAsynclog = jasynclog->getBool();
    }
    if (auto jname = json.get_ptr("name")) {
      checkLogic(jname->isString(), "PoolRoute: name is not a string");
      asynclogName = jname->stringPiece().str();
    }
  }
  if (needAsynclog) {
    route = createAsynclogRoute(std::move(route), asynclogName);
  }

  return route;
}