mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-07 06:16:06 -10:00
fix(native): keep the remote bootstrap retry for a closed listener
A remote Runner has no process evidence on the controller host, so startup recovery cannot adopt a claimed remote startup that the drain suspended. Keep the existing same-run bootstrap retry for remote targets and detach only local Runner executions. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
a35ec8b845
commit
5dc63f24fb
2 files changed
+11
-7
No files matched your search
@@ -3292,11 +3292,13 @@ A graceful shutdown can also suspend a restart-recovery claim whose execution
|
||||
has not yet reached provider dispatch. That execution has lost its authority:
|
||||
it leaves the run running, its budget hold held and its workspace unmarked, and
|
||||
the next controller adopts the same run. It does not settle the run as failed.
|
||||
Shutdown closes the runtime API listener before it drains runs. A native
|
||||
Shutdown closes the runtime API listener before it drains runs. A local Runner
|
||||
execution that then needs the listener (for example, to give a new runner its
|
||||
callback origin) detaches the same way instead of failing. It keeps its claim,
|
||||
the drain suspends it, and the next controller adopts the run. A listener that
|
||||
never started is still a startup failure.
|
||||
the drain suspends it, and the next controller adopts the run. A remote Runner
|
||||
execution has no process evidence on the controller host, so it keeps the
|
||||
same-run bootstrap retry. A listener that never started is still a startup
|
||||
failure.
|
||||
Remote Runner processes use their authenticated connection lease as the bound
|
||||
on disconnected lifetime. The controller's shorter connection-recovery budget
|
||||
limits its own attempt; it must not terminate the remote owner while another
|
||||
|
||||
@@ -10707,11 +10707,13 @@ async function executePaperclipNativeSessionWithinScope(
|
||||
error = identityRedactor.redact(error);
|
||||
}
|
||||
// A closed runtime API listener means this process is shutting down; it
|
||||
// closes HTTP admission before it drains runs. Keep the claim for the
|
||||
// drain to suspend, so the next controller adopts the run without spending
|
||||
// a failure or a same-run retry.
|
||||
// closes HTTP admission before it drains runs. For a local Runner, keep the
|
||||
// claim for the drain to suspend: the next controller proves the Runner
|
||||
// process identity and adopts the run without spending a failure or a
|
||||
// same-run retry. A remote Runner has no process evidence on this host, so
|
||||
// it keeps the bootstrap retry below.
|
||||
if (nativeRunsDetachingForRestart.has(input.execution.binding.runId)
|
||||
|| error instanceof LocalRuntimeApiListenerClosedError) {
|
||||
|| (error instanceof LocalRuntimeApiListenerClosedError && input.runnerExecutionTarget?.kind !== "remote")) {
|
||||
await leaseRenewal.stop().catch(() => undefined);
|
||||
liveQuestions.close();
|
||||
activeNativeSessions.delete(input.execution.binding.runId);
|
||||
|
||||
Reference in new issue
Block a user