FailoverWithExptimeRoute::FailoverWithExptimeRoute(
  RouteHandleFactory<McrouterRouteHandleIf>& factory,
  const folly::dynamic& json)
    : failoverExptime_(60) {

  checkLogic(json.isObject(), "FailoverWithExptimeRoute is not object");

  std::vector<McrouterRouteHandlePtr> failoverTargets;

  if (json.count("failover")) {
    failoverTargets = factory.createList(json["failover"]);
  }

  failover_ = FailoverRoute<McrouterRouteHandleIf>(std::move(failoverTargets));

  if (json.count("normal")) {
    normal_ = factory.create(json["normal"]);
  }

  if (json.count("failover_exptime")) {
    checkLogic(json["failover_exptime"].isInt(),
               "failover_exptime is not integer");
    failoverExptime_ = json["failover_exptime"].asInt();
  }

  if (json.count("settings")) {
    settings_ = FailoverWithExptimeSettings(json["settings"]);
  }
}
McrouterRouteHandlePtr makeFailoverWithExptimeRoute(
    RouteHandleFactory<McrouterRouteHandleIf>& factory,
    const folly::dynamic& json) {
  checkLogic(json.isObject(), "FailoverWithExptimeRoute is not an object");
  auto jnormal = json.get_ptr("normal");
  checkLogic(jnormal, "FailoverWithExptimeRoute: normal not found");
  auto normal = factory.create(*jnormal);

  int32_t failoverExptime = 60;
  if (auto jexptime = json.get_ptr("failover_exptime")) {
    checkLogic(jexptime->isInt(), "FailoverWithExptimeRoute: "
                                  "failover_exptime is not an integer");
    failoverExptime = jexptime->getInt();
  }

  std::vector<McrouterRouteHandlePtr> failover;
  if (auto jfailover = json.get_ptr("failover")) {
    failover = factory.createList(*jfailover);
  }

  auto children = getFailoverChildren(std::move(normal),
                                      std::move(failover),
                                      failoverExptime);
  return makeFailoverRoute(json, std::move(children));
}
Ejemplo n.º 3
0
ShardSplitter::ShardSplitter(const folly::dynamic& json) {
  if (!json.isObject()) {
    return;
  }

  for (const auto& it : json.items()) {
    if (!it.second.isInt()) {
      LOG(ERROR) << "ShardSplitter: shard_splits value is not an int for "
                 << it.first.asString();
      continue;
    }

    auto splitCnt = it.second.asInt();
    if (splitCnt <= 0) {
      LOG(ERROR) << "ShardSplitter: shard_splits value <= 0 '"
                 << it.first.asString() << "': " << splitCnt;
    } else if (static_cast<size_t>(splitCnt) > kMaxSplits) {
      LOG(ERROR) << "ShardSplitter: shard_splits value > " << kMaxSplits
                 << " '" << it.first.asString() << "': " << splitCnt;
      shardSplits_.emplace(it.first.c_str(), kMaxSplits);
    } else {
      shardSplits_.emplace(it.first.c_str(), splitCnt);
    }
  }
}
Ejemplo n.º 4
0
McrouterRouteHandlePtr makeHashRoute(
  const folly::dynamic& json,
  std::vector<McrouterRouteHandlePtr> rh,
  size_t threadId) {

  std::string salt;
  folly::StringPiece funcType = Ch3HashFunc::type();
  if (json.isObject()) {
    if (auto jsalt = json.get_ptr("salt")) {
      checkLogic(jsalt->isString(), "HashRoute: salt is not a string");
      salt = jsalt->getString();
    }
    if (auto jhashFunc = json.get_ptr("hash_func")) {
      checkLogic(jhashFunc->isString(),
                 "HashRoute: hash_func is not a string");
      funcType = jhashFunc->stringPiece();
    }
  }

  if (funcType == Ch3HashFunc::type()) {
    return makeHashRouteCh3(std::move(rh), std::move(salt));
  } else if (funcType == Crc32HashFunc::type()) {
    return makeHashRouteCrc32(std::move(rh), std::move(salt));
  } else if (funcType == WeightedCh3HashFunc::type()) {
    WeightedCh3HashFunc func{json, rh.size()};
    return makeHashRouteWeightedCh3(std::move(rh), std::move(salt),
                                    std::move(func));
  } else if (funcType == ConstShardHashFunc::type()) {
    return makeHashRouteConstShard(std::move(rh), std::move(salt));
  } else if (funcType == "Latest") {
    return makeLatestRoute(json, std::move(rh), threadId);
  }
  throwLogic("Unknown hash function: {}", funcType);
}
Ejemplo n.º 5
0
ProxyConfig::ProxyConfig(proxy_t* proxy,
                         const folly::dynamic& json,
                         std::string configMd5Digest,
                         std::shared_ptr<PoolFactory> poolFactory)
  : poolFactory_(std::move(poolFactory)),
    configMd5Digest_(std::move(configMd5Digest)) {

  McRouteHandleProvider provider(proxy, *proxy->destinationMap, *poolFactory_);
  RouteHandleFactory<McrouterRouteHandleIf> factory(provider);

  checkLogic(json.isObject(), "Config is not an object");

  if (json.count("named_handles")) {
    checkLogic(json["named_handles"].isArray(), "named_handles is not array");
    for (const auto& it : json["named_handles"]) {
      factory.create(it);
    }
  }

  RouteSelectorMap routeSelectors;

  auto jRoute = json.get_ptr("route");
  auto jRoutes = json.get_ptr("routes");
  checkLogic(!jRoute || !jRoutes,
             "Invalid config: both 'route' and 'routes' are specified");
  checkLogic(jRoute || jRoutes, "No route/routes in config");
  if (jRoute) {
    routeSelectors[proxy->getRouterOptions().default_route] =
        std::make_shared<PrefixSelectorRoute>(factory, *jRoute);
  } else { // jRoutes
    checkLogic(jRoutes->isArray() || jRoutes->isObject(),
               "Config: routes is not array/object");
    if (jRoutes->isArray()) {
      for (const auto& it : *jRoutes) {
        checkLogic(it.isObject(), "RoutePolicy is not an object");
        auto jCurRoute = it.get_ptr("route");
        auto jAliases = it.get_ptr("aliases");
        checkLogic(jCurRoute, "RoutePolicy: no route");
        checkLogic(jAliases, "RoutePolicy: no aliases");
        checkLogic(jAliases->isArray(), "RoutePolicy: aliases is not an array");
        auto routeSelector =
            std::make_shared<PrefixSelectorRoute>(factory, *jCurRoute);
        for (const auto& alias : *jAliases) {
          checkLogic(alias.isString(), "RoutePolicy: alias is not a string");
          routeSelectors[alias.stringPiece()] = routeSelector;
        }
      }
    } else { // object
      for (const auto& it : jRoutes->items()) {
        checkLogic(it.first.isString(), "RoutePolicy: alias is not a string");
        routeSelectors[it.first.stringPiece()] =
            std::make_shared<PrefixSelectorRoute>(factory, it.second);
      }
    }
  }

  asyncLogRoutes_ = provider.releaseAsyncLogRoutes();
  proxyRoute_ = std::make_shared<ProxyRoute>(proxy, routeSelectors);
  serviceInfo_ = std::make_shared<ServiceInfo>(proxy, *this);
}
Ejemplo n.º 6
0
void Scheduler::startSurface(
    SurfaceId surfaceId,
    const std::string &moduleName,
    const folly::dynamic &initialProps,
    const LayoutConstraints &layoutConstraints,
    const LayoutContext &layoutContext) {
  std::lock_guard<std::mutex> lock(mutex_);

  auto shadowTree =
      std::make_unique<ShadowTree>(surfaceId, layoutConstraints, layoutContext);
  shadowTree->setDelegate(this);
  shadowTreeRegistry_.emplace(surfaceId, std::move(shadowTree));

#ifndef ANDROID

  // TODO: Is this an ok place to do this?
  auto serializedCommands = initialProps.find("serializedCommands");
  if (serializedCommands != initialProps.items().end()) {
    auto tree = TemplateRenderer::buildShadowTree(serializedCommands->second.asString(), surfaceId, folly::dynamic::object(), *componentDescriptorRegistry_);

    uiManagerDidFinishTransactionWithoutLock(surfaceId, std::make_shared<SharedShadowNodeList>(SharedShadowNodeList {tree}));
    // TODO: hydrate rather than replace
    uiManager_->startSurface(surfaceId, moduleName, initialProps);
  } else {
    uiManager_->startSurface(surfaceId, moduleName, initialProps);
  }
#endif
}
Ejemplo n.º 7
0
void PoolFactory::parseQos(std::string parentName, const folly::dynamic& jQos,
                           uint64_t& qosClass, uint64_t& qosPath) {
  if (!jQos.isObject()) {
    MC_LOG_FAILURE(opts_, memcache::failure::Category::kInvalidConfig,
                   "{}: qos must be an object.", parentName);
    return;
  }

  uint64_t prevClass = qosClass;
  if (auto jClass = jQos.get_ptr("class")) {
    if (jClass->isInt() && isQosClassValid(jClass->getInt())) {
      qosClass = jClass->getInt();
    } else {
      MC_LOG_FAILURE(opts_, memcache::failure::Category::kInvalidConfig,
                     "{}: qos.class must be an integer in the range [0, 4]",
                     parentName);
    }
  }
  if (auto jPath = jQos.get_ptr("path")) {
    if (jPath->isInt() && isQosPathValid(jPath->getInt())) {
      qosPath = jPath->getInt();
    } else {
      MC_LOG_FAILURE(opts_, memcache::failure::Category::kInvalidConfig,
                     "{}: qos.path must be an integer in the range [0, 3]",
                     parentName);
      qosClass = prevClass;
    }
  }
}
Ejemplo n.º 8
0
std::vector<double> WeightedChHashFuncBase::parseWeights(
    const folly::dynamic& json,
    size_t n) {
  std::vector<double> weights;
  checkLogic(
      json.isObject() && json.count("weights"),
      "WeightedChHashFunc: not an object or no weights");
  checkLogic(
      json["weights"].isArray(), "WeightedChHashFunc: weights is not array");
  const auto& jWeights = json["weights"];
  LOG_IF(ERROR, jWeights.size() < n)
      << "WeightedChHashFunc: CONFIG IS BROKEN!!! number of weights ("
      << jWeights.size() << ") is smaller than number of servers (" << n
      << "). Missing weights are set to 0.5";
  for (size_t i = 0; i < std::min(n, jWeights.size()); ++i) {
    const auto& weight = jWeights[i];
    checkLogic(weight.isNumber(), "WeightedChHashFunc: weight is not number");
    const auto weightNum = weight.asDouble();
    checkLogic(
        0 <= weightNum && weightNum <= 1.0,
        "WeightedChHashFunc: weight must be in range [0, 1.0]");
    weights.push_back(weightNum);
  }
  weights.resize(n, 0.5);
  return weights;
}
Ejemplo n.º 9
0
bool PhpConst::parseType(const folly::dynamic& cns) {
  auto it = cns.find("type");
  if (it != cns.items().end()) {
    m_kindOf = kindOfFromDynamic(it->second);
    m_cppType = typeString(it->second, false);
    return true;
  }
  return false;
}
YGDisplay yogaStyleDisplayFromDynamic(const folly::dynamic &value) {
  assert(value.isString());
  auto stringValue = value.asString();

  if (stringValue == "flex") { return YGDisplayFlex; }
  if (stringValue == "none") { return YGDisplayNone; }

  abort();
}
YGPositionType yogaStylePositionTypeFromDynamic(const folly::dynamic &value) {
  assert(value.isString());
  auto stringValue = value.asString();

  if (stringValue == "relative") { return YGPositionTypeRelative; }
  if (stringValue == "absolute") { return YGPositionTypeAbsolute; }

  abort();
}
Ejemplo n.º 12
0
McrouterRouteHandlePtr makeFailoverWithExptimeRoute(
    RouteHandleFactory<McrouterRouteHandleIf>& factory,
    const folly::dynamic& json) {
  checkLogic(json.isObject(), "FailoverWithExptimeRoute is not an object");

  McrouterRouteHandlePtr normal;
  if (auto jnormal = json.get_ptr("normal")) {
    normal = factory.create(*jnormal);
  }

  std::vector<McrouterRouteHandlePtr> failoverTargets;
  if (auto jfailover = json.get_ptr("failover")) {
    failoverTargets = factory.createList(*jfailover);
  }

  int32_t failoverExptime = 60;
  if (auto jexptime = json.get_ptr("failover_exptime")) {
    checkLogic(jexptime->isInt(), "FailoverWithExptimeRoute: "
                                  "failover_exptime is not an integer");
    failoverExptime = jexptime->getInt();
  }

  // Check if only one format is being used
  checkLogic(!(json.count("settings") && // old
        (json.count("failover_errors") || json.count("failover_tag"))), // new
      "Use either 'settings' (old format) or 'failover_errors' / 'failover_tag'"
    );

  // new format
  FailoverErrorsSettings failoverErrors;
  bool failoverTagging = false;
  if (auto jfailoverTag = json.get_ptr("failover_tag")) {
    checkLogic(jfailoverTag->isBool(),
               "FailoverWithExptime: failover_tag is not bool");
    failoverTagging = jfailoverTag->getBool();
  }
  if (auto jfailoverErrors = json.get_ptr("failover_errors")) {
    failoverErrors = FailoverErrorsSettings(*jfailoverErrors);
  }

  // old format
  if (auto jsettings = json.get_ptr("settings")) {
    VLOG(1) << "FailoverWithExptime: This config format is deprecated. "
               "Use 'failover_errors' instead of 'settings'.";
    auto oldSettings = FailoverWithExptimeSettings(*jsettings);
    failoverTagging = oldSettings.failoverTagging;
    failoverErrors = oldSettings.getFailoverErrors();
  }

  return makeFailoverWithExptimeRoute(
    std::move(normal),
    std::move(failoverTargets),
    failoverExptime,
    std::move(failoverErrors),
    failoverTagging);
}
YGOverflow yogaStyleOverflowFromDynamic(const folly::dynamic &value) {
  assert(value.isString());
  auto stringValue = value.asString();

  if (stringValue == "visible") { return YGOverflowVisible; }
  if (stringValue == "hidden") { return YGOverflowHidden; }
  if (stringValue == "scroll") { return YGOverflowScroll; }

  abort();
}
YGDirection yogaStyleDirectionFromDynamic(const folly::dynamic &value) {
  assert(value.isString());
  auto stringValue = value.asString();

  if (stringValue == "inherit") { return YGDirectionInherit; }
  if (stringValue == "ltr") { return YGDirectionLTR; }
  if (stringValue == "rtl") { return YGDirectionRTL; }

  abort();
}
YGWrap yogaStyleWrapFromDynamic(const folly::dynamic &value) {
  assert(value.isString());
  auto stringValue = value.asString();

  if (stringValue == "no-wrap") { return YGWrapNoWrap; }
  if (stringValue == "wrap") { return YGWrapWrap; }
  if (stringValue == "wrap-reverse") { return YGWrapWrapReverse; }

  abort();
}
Ejemplo n.º 16
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));
}
YGFlexDirection yogaStyleFlexDirectionFromDynamic(const folly::dynamic &value) {
  assert(value.isString());
  auto stringValue = value.asString();

  if (stringValue == "column") { return YGFlexDirectionColumn; }
  if (stringValue == "column-reverse") { return YGFlexDirectionColumnReverse; }
  if (stringValue == "row") { return YGFlexDirectionRow; }
  if (stringValue == "row-reverse") { return YGFlexDirectionRowReverse; }

  abort();
}
Ejemplo n.º 18
0
PoolFactory::PoolJson PoolFactory::parsePool(const folly::dynamic& json) {
  checkLogic(json.isString() || json.isObject(),
             "Pool should be a string (name of pool) or an object");
  if (json.isString()) {
    return parseNamedPool(json.stringPiece());
  }
  auto jname = json.get_ptr("name");
  checkLogic(jname && jname->isString(), "Pool should have string 'name'");
  pools_.emplace(jname->stringPiece(), std::make_pair(json, PoolState::NEW));
  return parseNamedPool(jname->stringPiece());
}
Ejemplo n.º 19
0
std::shared_ptr<ClientPool>
PoolFactory::parsePool(const folly::dynamic& json) {
  checkLogic(json.isString() || json.isObject(),
             "Pool should be a string (name of pool) or an object");
  if (json.isString()) {
    return parsePool(json.stringPiece().str(), json);
  } else {
    auto name = json.get_ptr("name");
    checkLogic(name && name->isString(), "Pool should have string 'name'");
    return parsePool(name->stringPiece().str(), json);
  }
}
YGFloatOptional yogaStyleOptionalFloatFromDynamic(const folly::dynamic &value) {
  if (value.isNumber()) {
    return YGFloatOptional(value.asDouble());
  } else if (value.isString()) {
    const auto stringValue = value.asString();
    if (stringValue == "auto") {
      return YGFloatOptional();
    }
  }

  abort();
}
Ejemplo n.º 21
0
PoolFactory::PoolFactory(const folly::dynamic& config, ConfigApiIf& configApi)
    : configApi_(configApi) {
  checkLogic(config.isObject(), "config is not an object");
  if (auto jpools = config.get_ptr("pools")) {
    checkLogic(jpools->isObject(), "config: 'pools' is not an object");

    for (const auto& it : jpools->items()) {
      pools_.emplace(
          it.first.stringPiece(), std::make_pair(it.second, PoolState::NEW));
    }
  }
}
Ejemplo n.º 22
0
FailoverErrorsSettings::List::List(const folly::dynamic& json) {
  checkLogic(json.isArray(), "List of failover errors is not an array.");

  std::vector<std::string> errors;
  errors.reserve(json.size());
  for (const auto& elem : json) {
    checkLogic(elem.isString(), "Failover error {} is not a string", elem);
    errors.push_back(elem.getString());
  }

  init(std::move(errors));
}
Ejemplo n.º 23
0
bool PhpConst::inferType(const folly::dynamic& cns) {
  auto it = cns.find("value");
  if (it != cns.items().end()) {
    m_kindOf = kindOfFromValue(it->second);
    auto typeIt = g_typeMap.find((int)m_kindOf);
    if (typeIt != g_typeMap.end()) {
      m_cppType = typeIt->second;
      return true;
    }
  }
  return false;
}
Ejemplo n.º 24
0
static fbstring getFollyDynamicDefaultString(const folly::dynamic& d,
                                             const fbstring& key,
                                             const fbstring& def) {
  auto it = d.find(key);
  if (it == d.items().end()) {
    return def;
  }
  auto val = it->second;
  if (val.isNull()) {
    return def;
  }
  return val.asString();
}
YGJustify yogaStyleJustifyFromDynamic(const folly::dynamic &value) {
  assert(value.isString());
  auto stringValue = value.asString();

  if (stringValue == "flex-start") { return YGJustifyFlexStart; }
  if (stringValue == "center") { return YGJustifyCenter; }
  if (stringValue == "flex-end") { return YGJustifyFlexEnd; }
  if (stringValue == "space-between") { return YGJustifySpaceBetween; }
  if (stringValue == "space-around") { return YGJustifySpaceAround; }
  if (stringValue == "space-evenly") { return YGJustifySpaceEvenly; }

  abort();
}
Ejemplo n.º 26
0
std::function<void(folly::dynamic)> makeCallback(
    std::weak_ptr<Instance> instance, const folly::dynamic& callbackId) {
  if (!callbackId.isInt()) {
    throw std::invalid_argument("Expected callback(s) as final argument");
  }

  auto id = callbackId.getInt();
  return [winstance = std::move(instance), id](folly::dynamic args) {
    if (auto instance = winstance.lock()) {
      instance->callJSCallback(id, std::move(args));
    }
  };
}
Ejemplo n.º 27
0
int64_t convertDynamicIfIntegral(const folly::dynamic& val) {
  if (val.isInt()) {
    return val.getInt();
  }
  double dbl = val.getDouble();
  int64_t result = static_cast<int64_t>(dbl);
  if (dbl != result) {
    throwNewJavaException(
      exceptions::gUnexpectedNativeTypeExceptionClass,
      "Tried to read an int, but got a non-integral double: %f", dbl);
  }
  return result;
}
Ejemplo n.º 28
0
McrouterRouteHandlePtr makeLatestRoute(
    RouteHandleFactory<McrouterRouteHandleIf>& factory,
    const folly::dynamic& json) {
  std::vector<McrouterRouteHandlePtr> children;
  if (json.isObject()) {
    if (auto jchildren = json.get_ptr("children")) {
      children = factory.createList(*jchildren);
    }
  } else {
    children = factory.createList(json);
  }
  return makeLatestRoute(json, std::move(children));
}
Ejemplo n.º 29
0
std::pair<std::shared_ptr<ClientPool>, std::vector<McrouterRouteHandlePtr>>
McRouteHandleProvider::makePool(const folly::dynamic& json) {
  checkLogic(json.isString() || json.isObject(),
             "Pool should be a string (name of pool) or an object");
  auto pool = poolFactory_.parsePool(json);
  std::vector<McrouterRouteHandlePtr> destinations;
  for (const auto& client : pool->getClients()) {
    auto pdstn = destinationMap_.fetch(*client);
    auto route = makeDestinationRoute(client, std::move(pdstn));
    destinations.push_back(std::move(route));
  }

  return std::make_pair(std::move(pool), std::move(destinations));
}
Ejemplo n.º 30
0
JSValueRef Value::fromDynamicInner(JSContextRef ctx, const folly::dynamic& obj) {
  switch (obj.type()) {
    // For primitive types (and strings), just create and return an equivalent JSValue
    case folly::dynamic::Type::NULLT:
      return JSC_JSValueMakeNull(ctx);

    case folly::dynamic::Type::BOOL:
      return JSC_JSValueMakeBoolean(ctx, obj.getBool());

    case folly::dynamic::Type::DOUBLE:
      return JSC_JSValueMakeNumber(ctx, obj.getDouble());

    case folly::dynamic::Type::INT64:
      return JSC_JSValueMakeNumber(ctx, obj.asDouble());

    case folly::dynamic::Type::STRING:
      return JSC_JSValueMakeString(ctx, String(ctx, obj.getString().c_str()));

    case folly::dynamic::Type::ARRAY: {
      // Collect JSValue for every element in the array
      JSValueRef vals[obj.size()];
      for (size_t i = 0; i < obj.size(); ++i) {
        vals[i] = fromDynamicInner(ctx, obj[i]);
      }
      // Create a JSArray with the values
      JSValueRef arr = JSC_JSObjectMakeArray(ctx, obj.size(), vals, nullptr);
      return arr;
    }

    case folly::dynamic::Type::OBJECT: {
      // Create an empty object
      JSObjectRef jsObj = JSC_JSObjectMake(ctx, nullptr, nullptr);
      // Create a JSValue for each of the object's children and set them in the object
      for (auto it = obj.items().begin(); it != obj.items().end(); ++it) {
        JSC_JSObjectSetProperty(
          ctx,
          jsObj,
          String(ctx, it->first.asString().c_str()),
          fromDynamicInner(ctx, it->second),
          kJSPropertyAttributeNone,
          nullptr);
      }
      return jsObj;
    }
    default:
      // Assert not reached
      LOG(FATAL) << "Trying to convert a folly object of unsupported type.";
      return JSC_JSValueMakeNull(ctx);
  }
}