in bistro/thrift/ThriftConversion.cpp [130:203]
cpp2::BistroJobConfig toThrift(const std::string& name, const dynamic& d) {
// Defaults for "optional" fields are set by the .thrift file.
cpp2::BistroJobConfig config;
*config.name_ref() = name;
folly::DynamicParser p(folly::DynamicParser::OnError::RECORD, &d);
p.optional("enabled", [&](bool b) { *config.enabled_ref() = b; });
p.optional(
"owner", [&](std::string&& s) { *config.owner_ref() = std::move(s); });
p.optional("priority", [&](double p) { *config.priority_ref() = p; });
*config.config_ref() = "{}"; // No default in .thrift file :/
p.optional(
"config", [&]() { *config.config_ref() = folly::toJson(p.value()); });
// Since this toThrift is meant to be used on the output of toDynamic, it
// is not an error to have something in "errors".
p.optional(
"errors", [&]() { *config.error_ref() = folly::toJson(p.value()); });
p.optional("create_time", [&](int64_t n) { *config.createTime_ref() = n; });
p.optional("modify_time", [&](int64_t n) { *config.modifyTime_ref() = n; });
p.optional("level_for_tasks", [&](std::string&& s) {
*config.levelForTasks_ref() = std::move(s);
});
p.optional("resources", [&]() {
p.objectItems([&](std::string&& resourceName, int64_t amount) {
config.resources_ref()[resourceName] = amount;
});
});
p.optional("filters", [&]() {
p.objectItems([&](std::string&& filterName, const folly::dynamic& v) {
config.filters_ref()[filterName] = toThrift(v);
});
});
{
folly::Optional<std::chrono::milliseconds> maybe_kill_ms;
parseKillOrphanTasksAfter(&p, &maybe_kill_ms);
if (maybe_kill_ms.has_value()) {
config.killOrphanTasksAfterSec_ref() = 0.001 * maybe_kill_ms->count();
} else {
apache::thrift::unset_unsafe(config.killOrphanTasksAfterSec_ref());
}
}
parseTaskSubprocessOptions(&p, &(*config.taskSubprocessOptions_ref()));
parseKillRequest(&p, &(*config.killRequest_ref()));
p.optional("version_id", [&](int64_t n) { *config.versionID_ref() = n; });
p.optional("level_for_host_placement", [&](std::string&& s) {
*config.levelForHostPlacement_ref() = std::move(s);
});
p.optional("host_placement", [&](std::string&& s) {
*config.hostPlacement_ref() = std::move(s);
});
p.optional("backoff", [&]() {
p.arrayItems([&](const folly::dynamic& v) {
if (v.isInt()) {
config.backoffValues_ref()->push_back(v.asInt());
} else if (v.isString() && v.asString() == "repeat") {
*config.backoffRepeat_ref() = true;
} else if (!v.isString() || v.asString() != "fail") {
throw std::runtime_error("Unknown backoff value");
}
});
});
p.optional("depends_on", [&]() {
p.arrayItems([&](std::string&& dep_name) {
config.dependsOn_ref()->emplace_back(std::move(dep_name));
});
});
auto errors = p.releaseErrors();
if (!errors.empty()) {
// Should never happen:
throw BistroException(
"Failed to produce BistroJobConfig: ", folly::toJson(errors)
);
}
return config;
}