Keep remote process identity live through runner restart wrappers

Forward the asynchronous start-time getter instead of freezing its initial undefined value when decorating a launched handle. Cover both the initial launch and a replacement handle.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dotta 2026-09-10 15:14:41 -05:00
parent 6ae2dc5de7
commit b58c10611a
2 changed files with 38 additions and 0 deletions

View File

@ -164,6 +164,40 @@ it.skipIf(process.platform === "win32")(
},
);
it("retains asynchronously resolved process identity through the restart wrapper", async () => {
const starts: Array<{ startedAt?: string }> = [];
const handle = spawnRunner({
connection: { mode: "connect", connectUrl: "ws://127.0.0.1:43127" },
stateDirectory: "/tmp/paperclip-runner-test",
identity,
ticket: "bootstrap-ticket",
maxOutboxBytes: 256 * 1024,
p0ReserveBytes: 64 * 1024,
runnerVersion: expectedRunnerVersion,
runnerDigest: expectedRunnerDigest,
processLauncher: () => {
const process: { startedAt?: string } = {};
starts.push(process);
return {
child: { pid: 42, exitCode: null, signalCode: null, kill: () => true },
completion: Promise.resolve({ code: 0, signal: null, stdout: "", stderr: "" }),
get startedAt() { return process.startedAt; },
};
},
});
expect(handle.startedAt).toBeUndefined();
await Promise.resolve();
starts[0]!.startedAt = "2026-09-10T20:09:39.848Z";
expect(handle.startedAt).toBe(starts[0]!.startedAt);
const replacement = handle.restart("replacement-ticket");
expect(replacement.startedAt).toBeUndefined();
starts[1]!.startedAt = "2026-09-10T20:10:00.000Z";
expect(replacement.startedAt).toBe(starts[1]!.startedAt);
expect(handle.startedAt).toBe(starts[0]!.startedAt);
});
it("pins the ACPX launch profile in runner startup arguments and restarts", () => {
const launches: RunnerProcessLaunchSpec[] = [];
const handle = spawnRunner({

View File

@ -2212,6 +2212,10 @@ export function spawnRunner(options: {
const environment = runnerEnvironment(options.ticket, options.environment);
const withRestart = (handle: RunnerProcessHandle): RunnerProcessHandle => ({
...handle,
// Remote launchers resolve process identity after returning the handle.
get startedAt() {
return handle.startedAt;
},
restart: (ticket) => spawnRunner({ ...options, ticket }),
});
if (options.processLauncher !== undefined) {