cpp2::BistroJobConfig toThrift()

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