Ctrl K
ComunidadGuías…

lib/loop-registry-occurrence.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
var recordRevision = require("./record-revision");

function attachLoopRegistryOccurrence(ctx) {
  function normalize(id, now) {
    var rec = ctx.getById(id);
    if (!rec || !rec.enabled || !rec.scheduleRule || !rec.nextRunAt || rec.nextRunAt > now - 60000) return rec;
    var next = ctx.nextRecordRunTime(rec, now - 60000);
    if (Number(next) === Number(rec.nextRunAt)) return rec;
    var previous = JSON.parse(JSON.stringify(rec));
    rec.nextRunAt = next;
    if (!next) rec.enabled = false;
    if (!ctx.save()) { recordRevision.restoreRecord(rec, previous); return null; }
    ctx.changed();
    return rec;
  }

  function markNeedsOwner(id) {
    var rec = ctx.getById(id);
    if (!rec || rec.needsOwner === true) return false;
    var previous = JSON.parse(JSON.stringify(rec));
    rec.needsOwner = true;
    rec.setupRequired = "owner";
    rec.enabled = false;
    rec.nextRunAt = null;
    rec.scheduleEpoch = Math.max(1, Number(rec.scheduleEpoch) || 1) + 1;
    rec.updatedAt = recordRevision.nextRevision(rec);
    if (!ctx.save()) { recordRevision.restoreRecord(rec, previous); return false; }
    ctx.changed();
    return true;
  }

  function prepare(id, occurrenceAt) {
    var rec = ctx.getById(id);
    if (!rec || !rec.enabled || Number(rec.nextRunAt) !== Number(occurrenceAt)) return { ok: false, error: "The scheduled occurrence is stale." };
    var previous = JSON.parse(JSON.stringify(rec));
    var prepared = ctx.prepareTrigger ? ctx.prepareTrigger(rec) : null;
    if (prepared && prepared.ok === false) return prepared;
    ctx.scheduledRuns.prepareRecord(rec, prepared);
    if (!ctx.save()) { recordRevision.restoreRecord(rec, previous); return { ok: false, error: ctx.lastSaveError() || "The occurrence reservation could not be stored." }; }
    ctx.changed();
    if (prepared && prepared.skippedRun) ctx.scheduledRuns.notifyTerminal(rec, prepared.skippedRun);
    return { ok: true, value: prepared };
  }

  function trigger(id, prepared) {
    var rec = ctx.getById(id);
    if (!rec) throw new Error("The scheduled record was deleted.");
    if (ctx.onTrigger) ctx.onTrigger(rec, prepared);
  }

  function advance(id, occurrenceAt, result) {
    var rec = ctx.getById(id);
    if (!rec || Number(rec.nextRunAt) !== Number(occurrenceAt)) return false;
    var previous = JSON.parse(JSON.stringify(rec));
    var now = Date.now();
    rec.lastRunAt = result === "interrupted" ? occurrenceAt : now;
    if (result) rec.lastRunResult = result;
    if (rec.scheduleRule) ctx.scheduleRule.recordScheduleStartState(rec, occurrenceAt);
    if (rec.cron || rec.scheduleRule) {
      rec.nextRunAt = ctx.nextRecordRunTime(rec, now);
      if (rec.scheduleRule && !rec.nextRunAt) rec.enabled = false;
    } else {
      rec.nextRunAt = null;
      rec.enabled = false;
    }
    if (!ctx.save()) { recordRevision.restoreRecord(rec, previous); return false; }
    ctx.changed();
    return true;
  }

  function complete(id, occurrenceAt) { return advance(id, occurrenceAt, null); }
  function reconcile(id, occurrenceAt) { return advance(id, occurrenceAt, "interrupted"); }

  return { normalize: normalize, markNeedsOwner: markNeedsOwner, prepare: prepare, trigger: trigger, complete: complete, reconcile: reconcile };
}

module.exports = { attachLoopRegistryOccurrence: attachLoopRegistryOccurrence };