Ctrl K
ComunidadGuías…

lib/project-lifecycle-runtime.js

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

Archivo original ↗Preguntar a KiBot
// Retain failed shutdown handles so an explicitly reviewed recovery can retry them.
var crypto = require('crypto');
var witnesses = require('./project-lifecycle-process-witness');
function attachLifecycleRuntime(ctx) {
  var epoch = crypto.randomUUID(), retired = new Map();
  function target(slug, project) {
    var status = project.getStatus();
    return { slug: slug, path: status.path, projectKnowledgeId: status.projectKnowledgeId || null, epoch: epoch };
  }
  function key(item) { return JSON.stringify([item.slug, item.path, item.projectKnowledgeId]); }
  function matches(item, project) { return key(item) === key(target(item.slug, project)); }
  function targets(slug) {
    var out = [], witness = witnesses.capture();
    ctx.projects.forEach(function (project, candidate) {
      if (candidate === slug || candidate.indexOf(slug + '--') === 0) out.push(Object.assign(target(candidate, project), { witness: witness }));
    });
    return out;
  }
  function stop(item, project) {
    var id = key(item), previous = retired.get(id);
    if (previous && previous.project !== project) {
      if (!previous.closed) throw new Error('An earlier runtime with this identity has not confirmed closure.');
      previous = null;
    }
    if (previous && previous.running) return previous.running;
    if (previous && previous.closed) return Promise.resolve(true);
    var state = previous || { project: project, target: item, closed: false };
    retired.set(id, state);
    state.running = Promise.resolve().then(function () { return state.project.destroy(); }).then(function (result) {
      if (result !== true) throw new Error('Project runtime closure was not acknowledged: ' + item.slug);
      state.closed = true; return true;
    }).finally(function () { state.running = null; });
    return state.running;
  }
  async function close(items, proof) {
    for (var item of items) {
      var live = ctx.projects.get(item.slug), previous = retired.get(key(item));
      if (live) {
        if (!matches(item, live)) throw new Error('A replacement runtime occupies this registration.');
        ctx.projects.delete(item.slug);
        await stop(item, live);
      } else if (previous) await stop(item, previous.project);
      else if (!proof && !witnesses.confirmsExit(item.witness)) throw new Error('Runtime closure evidence is unavailable on this host. Keep the operation pending until its original host confirms closure.');
    }
    return true;
  }
  function shutdown() { return Promise.all(Array.from(retired.values()).filter(function (item) { return !item.closed; }).map(function (item) { return stop(item.target, item.project); })); }
  return { targets: targets, close: close, shutdown: shutdown };
}
module.exports = { attachLifecycleRuntime: attachLifecycleRuntime };