hydra-evaluator: add a 'ONE_AT_A_TIME' evaluator style

[?]
Mar 4, 2020, 12:53 AM
UANT7MOVK62YKFDQ5AJU2XETFKPUAEMJ4WJPRNJ7OJXN2E6DOFLQC

Dependencies

  • [2] K6CGDFOT hydra-evaluator: make the logic of the scheduler easier to read
  • [3] FYO6NECE hydra
  • [4] 2YXO5ZGQ Hydra/28: Rename "scheduler" to "evaluator"
  • [5] P6EWEJHL hydra-evaluator: Allow setting the maximum number of concurrent evaluations
  • [6] C3AG65SW Add one-shot jobsets
  • [7] AMI4DGBK Don't trigger evaluation of disabled jobsets
  • [8] PCKLFRT5 Support push notification of repository changes
  • [9] K22TMPH5 Make the info tables less compressed
  • [10] 4YCF3KBG Concurrent hydra-evaluator
  • [11] OX6NYJDV Split viewing and editing a jobset
  • [12] W4G5MZZS hydra-evaluator improvements
  • [13] KN3VYE5P * Cleaned up the foreign key constraints.
  • [14] ODNCGFQ5 * Improved the navigation bar: don't include all projects (since that
  • [*] 3HZY24CX * Make jobsets viewable under
  • [*] N22GPKYT * Put info about logs / build products in the DB.

Change contents

  • edit in src/hydra-evaluator/hydra-evaluator.cc at line 18
    [3.166]
    [3.761]
    enum class EvaluationStyle
    {
    SCHEDULE = 1,
    ONESHOT = 2,
    ONE_AT_A_TIME = 3,
    };
  • edit in src/hydra-evaluator/hydra-evaluator.cc at line 34
    [3.925]
    [3.925]
    std::optional<EvaluationStyle> evaluation_style;
  • replacement in src/hydra-evaluator/hydra-evaluator.cc at line 71
    [3.1527][3.1527:1664]()
    ("select project, j.name, lastCheckedTime, triggerTime, checkInterval from Jobsets j join Projects p on j.project = p.name "
    [3.1527]
    [3.1664]
    ("select project, j.name, lastCheckedTime, triggerTime, checkInterval, j.enabled as jobset_enabled from Jobsets j join Projects p on j.project = p.name "
  • edit in src/hydra-evaluator/hydra-evaluator.cc at line 89
    [3.2284]
    [3.2284]
    switch (row["jobset_enabled"].as<int>(0)) {
    case 1:
    jobset.evaluation_style = EvaluationStyle::SCHEDULE;
    break;
    case 2:
    jobset.evaluation_style = EvaluationStyle::ONESHOT;
    break;
    case 3:
    jobset.evaluation_style = EvaluationStyle::ONE_AT_A_TIME;
    break;
    }
  • edit in src/hydra-evaluator/hydra-evaluator.cc at line 155
    [2.111]
    [2.111]
    debug("shouldEvaluate %s:%s? no: already running",
    jobset.name.first, jobset.name.second);
  • replacement in src/hydra-evaluator/hydra-evaluator.cc at line 160
    [2.148][2.148:220]()
    if (jobset.triggerTime == std::numeric_limits<time_t>::max()) {
    [2.148]
    [2.220]
    if (jobset.triggerTime != std::numeric_limits<time_t>::max()) {
  • edit in src/hydra-evaluator/hydra-evaluator.cc at line 162
    [2.277]
    [2.277]
    debug("shouldEvaluate %s:%s? yes: requested",
    jobset.name.first, jobset.name.second);
  • edit in src/hydra-evaluator/hydra-evaluator.cc at line 170
    [2.480]
    [2.480]
    debug("shouldEvaluate %s:%s? no: checkInterval <= 0",
    jobset.name.first, jobset.name.second);
  • edit in src/hydra-evaluator/hydra-evaluator.cc at line 174
    [2.516]
    [2.516]
    if (jobset.lastCheckedTime + jobset.checkInterval <= time(0)) {
    // Time to schedule a fresh evaluation. If the jobset
    // is a ONE_AT_A_TIME jobset, ensure the previous jobset
    // has no remaining, unfinished work.
    auto conn(dbPool.get());
  • edit in src/hydra-evaluator/hydra-evaluator.cc at line 182
    [2.517]
    [2.517]
    pqxx::work txn(*conn);
  • replacement in src/hydra-evaluator/hydra-evaluator.cc at line 184
    [2.518][2.518:666]()
    if (jobset.lastCheckedTime + jobset.checkInterval <= time(0)) {
    // Time to schedule a fresh evaluation
    return true;
    [2.518]
    [2.666]
    if (jobset.evaluation_style == EvaluationStyle::ONE_AT_A_TIME) {
    auto evaluation_res = txn.parameterized
    ("select id from JobsetEvals "
    "where project = $1 and jobset = $2 "
    "order by id desc limit 1")
    (jobset.name.first)
    (jobset.name.second)
    .exec();
    if (evaluation_res.empty()) {
    // First evaluation, so allow scheduling.
    debug("shouldEvaluate(one-at-a-time) %s:%s? yes: no prior eval",
    jobset.name.first, jobset.name.second);
    return true;
    }
    auto evaluation_id = evaluation_res[0][0].as<int>();
    auto unfinished_build_res = txn.parameterized
    ("select id from Builds "
    "join JobsetEvalMembers "
    " on (JobsetEvalMembers.build = Builds.id) "
    "where JobsetEvalMembers.eval = $1 "
    " and builds.finished = 0 "
    " limit 1")
    (evaluation_id)
    .exec();
    // If the previous evaluation has no unfinished builds
    // schedule!
    if (unfinished_build_res.empty()) {
    debug("shouldEvaluate(one-at-a-time) %s:%s? yes: no unfinished builds",
    jobset.name.first, jobset.name.second);
    return true;
    } else {
    debug("shouldEvaluate(one-at-a-time) %s:%s? no: at least one unfinished build",
    jobset.name.first, jobset.name.second);
    return false;
    }
    } else {
    // EvaluationStyle::ONESHOT, EvaluationStyle::SCHEDULED
    debug("shouldEvaluate(oneshot/scheduled) %s:%s? yes: checkInterval elapsed",
    jobset.name.first, jobset.name.second);
    return true;
    }
  • replacement in src/lib/Hydra/Controller/Jobset.pm at line 229
    [3.108][3.108:149]()
    die if $enabled < 0 || $enabled > 2;
    [3.108]
    [3.2074]
    die if $enabled < 0 || $enabled > 3;
  • edit in src/root/edit-jobset.tt at line 71
    [3.684]
    [3.684]
    <button type="button" class="btn" value="3">One-at-a-time</button>
  • replacement in src/root/jobset.tt at line 132
    [3.852][3.852:992]()
    <td>[% IF jobset.enabled == 0; "Disabled"; ELSIF jobset.enabled == 1; "Enabled"; ELSIF jobset.enabled == 2; "One-shot"; END %]</td>
    [3.852]
    [3.992]
    <td>[% IF jobset.enabled == 0; "Disabled"; ELSIF jobset.enabled == 1; "Enabled"; ELSIF jobset.enabled == 2; "One-shot"; ELSIF jobset.enabled == 3; "One-at-a-time"; END %]</td>
  • replacement in src/sql/hydra.sql at line 64
    [3.3384][3.1675:1764]()
    enabled integer not null default 1, -- 0 = disabled, 1 = enabled, 2 = one-shot
    [3.3384]
    [3.5089]
    enabled integer not null default 1, -- 0 = disabled, 1 = enabled, 2 = one-shot, 3 = one-at-a-time