typename RouterInfo::RouteHandlePtr makeLatencyInjectionRoute()

in mcrouter/routes/LatencyInjectionRoute.h [217:292]


typename RouterInfo::RouteHandlePtr makeLatencyInjectionRoute(
    RouteHandleFactory<typename RouterInfo::RouteHandleIf>& factory,
    const folly::dynamic& json) {
  checkLogic(json.isObject(), "LoadBalancerRoute: config is not an object.");

  auto jChild = json.get_ptr("child");
  checkLogic(
      jChild != nullptr, "LatencyInjectionRoute: 'child' property is missing.");
  auto child = factory.create(*jChild);

  auto jBeforeLatency = json.get_ptr("before_latency_ms");
  auto jAfterLatency = json.get_ptr("after_latency_ms");
  auto jTotalLatency = json.get_ptr("total_latency_ms");
  auto jRequestLatency = json.get_ptr("request_payload_latency");
  checkLogic(
      jBeforeLatency != nullptr || jAfterLatency != nullptr ||
          jTotalLatency != nullptr || jRequestLatency != nullptr,
      "LatencyInjectionRoute must specify either 'before_latency_ms', "
      "'after_latency_ms', 'total_latency_ms' or 'request_payload_latency'");

  std::chrono::milliseconds beforeLatency{0};
  std::chrono::milliseconds afterLatency{0};
  std::chrono::milliseconds totalLatency{0};
  if (jBeforeLatency) {
    checkLogic(
        jBeforeLatency->isInt(),
        "LatencyInjectionRoute: 'before_latency_ms' must be an interger.");
    beforeLatency = std::chrono::milliseconds(jBeforeLatency->asInt());
  }
  if (jAfterLatency) {
    checkLogic(
        jAfterLatency->isInt(),
        "LatencyInjectionRoute: 'after_latency_ms' must be an interger.");
    afterLatency = std::chrono::milliseconds(jAfterLatency->asInt());
  }
  if (jTotalLatency) {
    checkLogic(
        jTotalLatency->isInt(),
        "LatencyInjectionRoute: 'total_latency_ms' must be an integer.");
    totalLatency = std::chrono::milliseconds(jTotalLatency->asInt());
  }

  bool requestLatency = false;
  if (jRequestLatency) {
    checkLogic(
        jRequestLatency->isBool(),
        "LatencyInjectionRoute: 'request_payload_latency' is not a bool");
    if (jRequestLatency->getBool()) {
      requestLatency = true;
    }
  }

  // Note that maxRequestLatency is in usecs.
  std::chrono::microseconds maxRequestLatency{0};
  auto jMaxRequestLatency = json.get_ptr("max_request_latency_us");
  if (jMaxRequestLatency) {
    checkLogic(
        jMaxRequestLatency->isInt(),
        "LatencyInjectionRoute: 'max_request_latency_us' is not an int");
    maxRequestLatency = std::chrono::microseconds(jMaxRequestLatency->asInt());
  }

  if (beforeLatency.count() == 0 && afterLatency.count() == 0 &&
      totalLatency.count() == 0 && !requestLatency) {
    // if we are not injecting any latency, optimize this rh away.
    return child;
  }

  return makeRouteHandleWithInfo<RouterInfo, LatencyInjectionRoute>(
      std::move(child),
      beforeLatency,
      afterLatency,
      totalLatency,
      requestLatency,
      maxRequestLatency);
}