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