@omercnet/paseo-omp 1.0.3-next.193.1 → 1.0.3-next.194.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omercnet/paseo-omp",
3
- "version": "1.0.3-next.193.1",
3
+ "version": "1.0.3-next.194.1",
4
4
  "type": "module",
5
5
  "description": "Paseo integration for OMP, including its direct provider and workspace tooling.",
6
6
  "license": "MIT",
@@ -1,2 +1,2 @@
1
1
  /** Release Please keeps this bundle-safe constant aligned with package.json. */
2
- export const PASEO_OMP_PACKAGE_VERSION = "1.0.3-next.193.1"; // x-release-please-version
2
+ export const PASEO_OMP_PACKAGE_VERSION = "1.0.3-next.194.1"; // x-release-please-version
@@ -12,6 +12,7 @@ import {
12
12
  type ProcessTreeCleanup,
13
13
  stopWindowsTree,
14
14
  terminatePosixProcessTree,
15
+ waitMs,
15
16
  } from "./omp-rpc-process";
16
17
  import {
17
18
  createOptionalMetadataSanitizer,
@@ -56,7 +57,10 @@ import {
56
57
  sanitizeHistoryResponseData,
57
58
  sanitizeLiveDisplayFrame,
58
59
  } from "./omp-rpc-protocol";
59
- import { boundedJsonBytes, OmpPublicError, utf8Bytes } from "./security";
60
+ import { boundedJsonBytes, OmpCleanupFailure, OmpPublicError, utf8Bytes } from "./security";
61
+
62
+ // Unverified close keeps the native session quarantined; these retries let a slow exit clear it.
63
+ const TREE_CLEANUP_RETRY_DELAYS_MS = [500, 1_000, 2_000, 4_000];
60
64
 
61
65
  type TimerHandle = number | NodeJS.Timeout;
62
66
  type SpawnProcess = (request: OmpSpawnRequest) => ChildProcessWithoutNullStreams;
@@ -483,7 +487,12 @@ export class OmpRpcProcess {
483
487
  }
484
488
  }
485
489
  const cleanup = await cleanupPromise;
486
- if (cleanup !== "verified") throw new Error("OMP RPC process tree cleanup failed");
490
+ if (cleanup !== "verified") {
491
+ throw new OmpCleanupFailure(
492
+ "OMP RPC process tree cleanup failed",
493
+ this.reverifyTreeCleanup(),
494
+ );
495
+ }
487
496
  if (process.platform === "win32" && !this.exited) {
488
497
  try {
489
498
  this.child.stdin.end();
@@ -496,8 +505,28 @@ export class OmpRpcProcess {
496
505
  !this.exited &&
497
506
  !(await this.waitForExit(PROCESS_STOP_TIMEOUT_MS))
498
507
  ) {
499
- throw new Error("OMP RPC process did not close after tree cleanup");
508
+ throw new OmpCleanupFailure(
509
+ "OMP RPC process did not close after tree cleanup",
510
+ this.reverifyTreeCleanup(),
511
+ );
512
+ }
513
+ }
514
+
515
+ private async reverifyTreeCleanup(): Promise<void> {
516
+ const pid = this.child.pid;
517
+ if (pid !== undefined) {
518
+ for (const delayMs of TREE_CLEANUP_RETRY_DELAYS_MS) {
519
+ await waitMs(delayMs);
520
+ const outcome = await this.terminateProcessTree(pid).catch(() => "failed");
521
+ if (
522
+ outcome === "verified" &&
523
+ (this.exited || (await this.waitForExit(PROCESS_STOP_TIMEOUT_MS)))
524
+ ) {
525
+ return;
526
+ }
527
+ }
500
528
  }
529
+ throw new Error("OMP RPC process tree cleanup is unverified");
501
530
  }
502
531
 
503
532
  private startTreeCleanup(): Promise<ProcessTreeCleanup> {