Ctrl K
ComunidadGuías…

cli-parent-lifetime.mjs

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

Archivo original ↗Preguntar a KiBot
import { GATEWAY_SHUTDOWN_RESERVE_MS } from "./gateway-shutdown-budget.mjs";

const parentKey = Symbol.for("openclaw.cliRespawnParent");
export const CLI_RESPAWN_PARENT_ENV = "OPENCLAW_CLI_RESPAWN_PARENT";
// Compiled executables cannot run a preload. Consume its one-child equivalent
// before any detached worker can inherit it, and reject a different parent.
const inheritedParent = process.env[CLI_RESPAWN_PARENT_ENV];
delete process.env[CLI_RESPAWN_PARENT_ENV];
if (inheritedParent === String(process.ppid)) {
  globalThis[parentKey] = { pid: process.ppid };
}
// Consume the private preload so later detached workers cannot inherit this contract.
export const CLI_PARENT_BOUND_PRELOAD = `data:text/javascript,${encodeURIComponent(`
  globalThis[Symbol.for("openclaw.cliRespawnParent")] = { pid: process.ppid };
  process.execArgv = process.execArgv.filter((arg, index, args) =>
    arg !== import.meta.url && !(arg === "--import" && args[index + 1] === import.meta.url));
`)}`;

/** Only the respawn producer opts in; detached update drivers keep independent custody. */
export function getCliParentPid() {
  return globalThis[parentKey]?.pid;
}

let terminating = false;
export function requestCliParentTermination(
  signal = () => {
    if (!process.emit("SIGTERM")) {
      process.kill(process.pid, "SIGTERM");
    }
  },
) {
  if (terminating) {
    return;
  }
  terminating = true;
  // Doctor's signal gate cancels work and settles rollback/restoration before exit.
  setTimeout(() => process.kill(process.pid, "SIGKILL"), GATEWAY_SHUTDOWN_RESERVE_MS).unref();
  signal();
}

export function watchCliRespawnParent() {
  const parent = globalThis[parentKey];
  if (!parent || parent.watching || !process.channel) {
    return;
  }
  parent.watching = true;
  process.once("disconnect", requestCliParentTermination);
  process.channel.unref();
  if (!process.connected) {
    requestCliParentTermination();
  }
}