@dsh-sup/dsh-core-linux-x64 0.1.5-BETA.8 → 0.1.5-BETA.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/core.cjs +91 -5
  2. package/package.json +1 -1
package/core.cjs CHANGED
@@ -348,7 +348,7 @@ var require_version = __commonJS({
348
348
  var fs2 = require("node:fs");
349
349
  var path2 = require("node:path");
350
350
  function guardVersion() {
351
- if (true) return String("0.1.5-BETA.8");
351
+ if (true) return String("0.1.5-BETA.9");
352
352
  try {
353
353
  return JSON.parse(fs2.readFileSync(path2.join(__dirname, "..", "..", "package.json"), "utf8")).version || "unknown";
354
354
  } catch {
@@ -783,6 +783,7 @@ var require_store = __commonJS({
783
783
  if (typeof raw.lastFailure === "string" || raw.lastFailure === null) record.procFieldOf("lastFailure", raw.lastFailure, true);
784
784
  if (typeof raw.lastRestartAt === "string" || raw.lastRestartAt === null) record.procFieldOf("lastRestartAt", raw.lastRestartAt, true);
785
785
  if (raw.upgradeHold === true) upgradeHold.enter();
786
+ if (raw.shellHalted === true && typeof g.setShellHalted === "function") g.setShellHalted(true);
786
787
  } catch {
787
788
  }
788
789
  try {
@@ -1346,7 +1347,9 @@ var require_collaborator = __commonJS({
1346
1347
  getEvents: g.getEvents,
1347
1348
  getInstances: g.getInstances,
1348
1349
  getViews: g.getViews,
1349
- getManagedObjects: g.getManagedObjects
1350
+ getManagedObjects: g.getManagedObjects,
1351
+ getShellHalted: g.getShellHalted,
1352
+ setShellHalted: g.setShellHalted
1350
1353
  });
1351
1354
  holder.store = store;
1352
1355
  const desired = createDesired({
@@ -3562,6 +3565,10 @@ var require_collaborators = __commonJS({
3562
3565
  setSince: (v) => {
3563
3566
  host._upgradeHoldSince = v;
3564
3567
  },
3568
+ getShellHalted: () => host._shellHalted,
3569
+ setShellHalted: (v) => {
3570
+ host._shellHalted = v;
3571
+ },
3565
3572
  stopProcess: (why) => host.stopProcess(why),
3566
3573
  tick: () => host.tick()
3567
3574
  });
@@ -4140,6 +4147,16 @@ var require_watchdog = __commonJS({
4140
4147
  const t = now();
4141
4148
  const procs = shellProcs();
4142
4149
  const alive = procs.length;
4150
+ if (alive > 0 && typeof o.onShellAlive === "function") {
4151
+ try {
4152
+ o.onShellAlive();
4153
+ } catch {
4154
+ }
4155
+ }
4156
+ if (typeof o.halted === "function" && o.halted()) {
4157
+ lastSkipReason = "\u4F1A\u8BDD\u9000\u51FA\u4E2D/\u7528\u6237\u5DF2\u9000\u51FA\uFF08\u4E0D\u62C9\u8D77\uFF09";
4158
+ return { skipped: "halted", reason: lastSkipReason };
4159
+ }
4143
4160
  if (alive > 0 && !everSawAlive) {
4144
4161
  everSawAlive = true;
4145
4162
  log("\u5DF2\u89C2\u6D4B\u5230\u684C\u9762\u58F3\u5728\u8FD0\u884C\uFF08pid=" + procs[0].pid + "\uFF09");
@@ -4185,7 +4202,12 @@ var require_watchdog = __commonJS({
4185
4202
  return { skipped: d.reason };
4186
4203
  }
4187
4204
  restarts.push(t);
4188
- const r = await shell.restartShell({ exePath: exe, procPattern });
4205
+ const r = await shell.restartShell({
4206
+ exePath: exe,
4207
+ procPattern,
4208
+ // 在飞复判(K4):杀旧壳与 spawn 之间有 ~8s 窗口,退出请求可能在窗口内到达。
4209
+ shouldAbort: typeof o.halted === "function" ? () => o.halted() : void 0
4210
+ });
4189
4211
  if (r && r.ok) {
4190
4212
  if (events) events.append("shell_watchdog_restart", { pid: r.pid, exe: r.exe, absentMs: absentForMs });
4191
4213
  log("\u684C\u9762\u58F3\u7F3A\u5931 " + Math.round(absentForMs / 1e3) + "s\uFF0C\u5DF2\u62C9\u8D77 pid=" + r.pid + " exe=" + r.exe);
@@ -5430,7 +5452,22 @@ var require_bootstrap = __commonJS({
5430
5452
  desktop: platform.desktop,
5431
5453
  logger: host.logger,
5432
5454
  events: host.events,
5433
- config: host.config
5455
+ config: host.config,
5456
+ // 门**下沉到看护域**(2026-09-18 修,K3):tick() 的一切调用者都受同一门约束。
5457
+ halted: () => !!(host._stopping || host._shellHalted || host._sessionHalting && host._sessionHalting()),
5458
+ // 壳已在线 = 用户重新打开了壳 -> 清除持久退出标记(否则自愈被永久抑制)。
5459
+ // ⚠ 只在**非退出中**才清:退出握手期间壳还会存活数百 ms,若此时误清,
5460
+ // 持久标记被写成 false,守卫重启后看护又把壳拉回(本修的核心场景)。
5461
+ onShellAlive: () => {
5462
+ if (!host._shellHalted) return;
5463
+ if (host._stopping) return;
5464
+ if (host._sessionHalting && host._sessionHalting()) return;
5465
+ host._shellHalted = false;
5466
+ try {
5467
+ host.writeState(true);
5468
+ } catch {
5469
+ }
5470
+ }
5434
5471
  });
5435
5472
  host._shellWatchdogTimer = setInterval(() => {
5436
5473
  Promise.resolve(host.shellWatchdog.tick()).catch(() => {
@@ -5624,6 +5661,40 @@ var require_shutdown = __commonJS({
5624
5661
  async function shutdownAll(host) {
5625
5662
  if (host._sessionHalting()) return { ok: true, already: true, sessionState: host._sessionState };
5626
5663
  host._setSessionState("stopping");
5664
+ host._shellHalted = true;
5665
+ try {
5666
+ host.writeState(true);
5667
+ } catch (e) {
5668
+ host.logger.warn && host.logger.warn("shutdownAll persist shellHalted: " + e.message);
5669
+ }
5670
+ if (host._shellWatchdogTimer) {
5671
+ clearInterval(host._shellWatchdogTimer);
5672
+ host._shellWatchdogTimer = null;
5673
+ }
5674
+ if (host._heartbeatTimer) {
5675
+ clearInterval(host._heartbeatTimer);
5676
+ host._heartbeatTimer = null;
5677
+ }
5678
+ if (host._timer) {
5679
+ clearInterval(host._timer);
5680
+ host._timer = null;
5681
+ }
5682
+ if (host._initialCheckTimer) {
5683
+ clearTimeout(host._initialCheckTimer);
5684
+ host._initialCheckTimer = null;
5685
+ }
5686
+ if (host._upgradeTimer) {
5687
+ clearInterval(host._upgradeTimer);
5688
+ host._upgradeTimer = null;
5689
+ }
5690
+ if (host._killTimer) {
5691
+ clearTimeout(host._killTimer);
5692
+ host._killTimer = null;
5693
+ }
5694
+ if (host._adoptKillTimer) {
5695
+ clearTimeout(host._adoptKillTimer);
5696
+ host._adoptKillTimer = null;
5697
+ }
5627
5698
  host.logger.info("[session] \u9000\u51FA\u6D41\u7A0B\u5F00\u59CB\uFF1A\u505C\u6B62\u5168\u90E8\u88AB\u7BA1\u5BF9\u8C61\u2026");
5628
5699
  host.events && host.events.append("shutdown_all", {});
5629
5700
  host._stopMainDsh();
@@ -8859,6 +8930,8 @@ var require_status = __commonJS({
8859
8930
  lastFailure: host._mLastFailure(),
8860
8931
  lastRestartAt: host._mLastRestartAt(),
8861
8932
  upgradeHold: host._upgradeHold,
8933
+ // 用户退出标记(跨守卫重启持久):退出后守卫重启不得凭看护把壳拉回。
8934
+ shellHalted: host._shellHalted === true,
8862
8935
  commandMissing: !!(host._mSpawnBlockedUntil() && Date.now() < host._mSpawnBlockedUntil()),
8863
8936
  dshTokenCaptured: !!(host.tokenService && host.tokenService.get("main")),
8864
8937
  tasks: host.tasks ? host.tasks.running().map((t) => ({ id: t.id, kind: t.kind, action: t.action, target: t.target, state: t.state })) : [],
@@ -11857,6 +11930,12 @@ var require_restart = __commonJS({
11857
11930
  if (!gone) {
11858
11931
  return { ok: false, error: "\u65E7\u58F3\u8FDB\u7A0B\u672A\u80FD\u5728\u8D85\u65F6\u5185\u9000\u51FA\uFF0C\u5DF2\u653E\u5F03\u91CD\u542F\uFF08\u907F\u514D\u53CC\u5B9E\u4F8B\uFF09", killed };
11859
11932
  }
11933
+ if (typeof o.shouldAbort === "function") {
11934
+ try {
11935
+ if (o.shouldAbort()) return { ok: false, aborted: true, error: "\u4F1A\u8BDD\u5DF2\u9000\u51FA/\u9000\u51FA\u4E2D\uFF0C\u5DF2\u653E\u5F03\u62C9\u8D77\u684C\u9762\u58F3", killed };
11936
+ } catch {
11937
+ }
11938
+ }
11860
11939
  try {
11861
11940
  const child = spawnOS.detachedIgnored(exe, [], { env: process.env });
11862
11941
  child.on("error", (e) => {
@@ -12408,6 +12487,7 @@ var require_core5 = __commonJS({
12408
12487
  host._stopping = false;
12409
12488
  host._sessionState = "starting";
12410
12489
  host._crashHalted = false;
12490
+ host._shellHalted = false;
12411
12491
  host._upgradeHold = false;
12412
12492
  host._upgradeHoldSince = null;
12413
12493
  host._timer = null;
@@ -24116,8 +24196,14 @@ var require_shell2 = __commonJS({
24116
24196
  req.resume();
24117
24197
  return send(403, {});
24118
24198
  }
24199
+ if (typeof sup._sessionHalting === "function" && sup._sessionHalting()) {
24200
+ req.resume();
24201
+ return send(409, { ok: false, error: "\u4F1A\u8BDD\u5DF2\u9000\u51FA/\u9000\u51FA\u4E2D\uFF0C\u62D2\u7EDD\u91CD\u542F\u684C\u9762\u58F3" });
24202
+ }
24119
24203
  req.resume();
24120
- return Promise.resolve(shell.restartShell()).then((r) => {
24204
+ return Promise.resolve(shell.restartShell({
24205
+ shouldAbort: () => typeof sup._sessionHalting === "function" && sup._sessionHalting()
24206
+ })).then((r) => {
24121
24207
  if (sup.events) sup.events.append("shell_restart_requested", { ok: r.ok, killed: r.killed || [], pid: r.pid || null });
24122
24208
  return send(r.ok ? 200 : 500, r);
24123
24209
  }).catch((e) => send(500, { ok: false, error: e.message }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-sup/dsh-core-linux-x64",
3
- "version": "0.1.5-BETA.8",
3
+ "version": "0.1.5-BETA.9",
4
4
  "description": "DSH lifecycle guard core (Node launcher) for linux-x64 — requires Node >=18.",
5
5
  "license": "UNLICENSED",
6
6
  "os": [