Files
hermes-agent/apps/desktop/electron/backend-connection-state.ts
T
brooklyn! 8607d6a52a fix(desktop): retain and cancel owned backend lifecycle work
Track pending starts, pre-claim children, and teardown removed from routing. Bound cleanup and cancel setup/update waits while preserving settled remote descriptors.

Co-authored-by: Gille <4317663+helix4u@users.noreply.github.com>

Co-authored-by: ChanPark03 <parkchan0302@gmail.com>
2026-09-11 07:33:17 -05:00

111 lines
2.6 KiB
TypeScript

export type BackendConnectionAttempt<TConnection> = {
generation: number
promise: Promise<TConnection> | null
}
export type BackendProcessOwner<TProcess> = {
generation: number
process: TProcess
}
export function createBackendConnectionState<TProcess, TConnection>() {
let generation = 0
let process: TProcess | null = null
let promise: Promise<TConnection> | null = null
let pendingPromise: Promise<TConnection> | null = null
return {
startAttempt(): BackendConnectionAttempt<TConnection> {
return { generation, promise: null }
},
setPromise(attempt: BackendConnectionAttempt<TConnection>, nextPromise: Promise<TConnection>): boolean {
if (attempt.generation !== generation) {
return false
}
attempt.promise = nextPromise
promise = nextPromise
pendingPromise = nextPromise
void nextPromise.then(
() => {
if (attempt.generation === generation && promise === nextPromise) {
pendingPromise = null
}
},
() => {
if (attempt.generation === generation && promise === nextPromise) {
pendingPromise = null
}
}
)
return true
},
isCurrentAttempt(attempt: BackendConnectionAttempt<TConnection>): boolean {
return attempt.generation === generation
},
attachProcess(
attempt: BackendConnectionAttempt<TConnection>,
nextProcess: TProcess
): BackendProcessOwner<TProcess> | null {
if (attempt.generation !== generation) {
return null
}
process = nextProcess
return { generation, process: nextProcess }
},
clearForCurrentProcess(owner: BackendProcessOwner<TProcess>): boolean {
if (owner.generation !== generation || owner.process !== process) {
return false
}
process = null
promise = null
pendingPromise = null
return true
},
clearPromiseForAttempt(attempt: BackendConnectionAttempt<TConnection>): boolean {
if (attempt.generation !== generation || (promise !== null && attempt.promise !== promise)) {
return false
}
promise = null
pendingPromise = null
return true
},
getProcess(): TProcess | null {
return process
},
getPromise(): Promise<TConnection> | null {
return promise
},
getPendingPromise(): Promise<TConnection> | null {
return pendingPromise
},
invalidate(): TProcess | null {
const currentProcess = process
generation += 1
process = null
promise = null
pendingPromise = null
return currentProcess
}
}
}