mirror of
https://github.com/wu736139669/hapi.git
synced 2026-10-13 20:09:55 +00:00
feat(opencode): open a fresh session on clear (#1300)
* test(opencode): specify fresh-session clear * feat(opencode): open a fresh session on clear * fix(opencode): release clear latch on cancel * fix(opencode): retry transient clear handoffs * fix(opencode): confirm clear archive delivery * fix(web): preserve superseded session access * fix(clear): invalidate transferred schedules * fix(runner): restore live spawn dedupe * fix(clear): preserve latched scheduled prompts * fix(runner): quarantine unverified children * fix(clear): retain handoff retry ownership * fix(runner): release recovered spawn dedupe * fix(clear): retain archive retry ownership * fix(clear): settle rejected immediate prompts * fix(clear): block reopening replaced sources * fix(clear): settle prompts when clear is cancelled * fix(clear): make fresh-session handoff durable * fix(clear): finalize only after native cleanup * fix(clear): abort failed native handoffs * fix(clear): gate recovery on cleanup proof * fix(clear): retry metadata persistence failures * fix(clear): preserve handoff ownership through teardown * fix(clear): abort incomplete cleanup reservations * fix(clear): require explicit exit before abort * fix(clear): verify owner exit before recovery * fix(clear): guard recovery handoff races * fix(clear): serialize cleanup callbacks * fix(clear): make callback retries idempotent * fix(clear): bind callbacks to reservations * fix(clear): recover pending spawns * fix(clear): deduplicate held prompts * fix(clear): validate redirect ownership * fix(clear): replay prompts in FIFO order * fix(clear): gate replacement delivery
This commit is contained in:
@@ -1098,7 +1098,7 @@ export class ApiSessionClient extends EventEmitter {
|
||||
return await this.drainLock(this.metadataLock, timeoutMs)
|
||||
}
|
||||
|
||||
async flush(options?: { timeoutMs?: number }): Promise<void> {
|
||||
async flush(options?: { timeoutMs?: number }): Promise<boolean> {
|
||||
const deadlineMs = Date.now() + (options?.timeoutMs ?? 5_000)
|
||||
const remainingMs = () => Math.max(0, deadlineMs - Date.now())
|
||||
|
||||
@@ -1106,37 +1106,44 @@ export class ApiSessionClient extends EventEmitter {
|
||||
if (materializationTask) {
|
||||
this.materializationDrainRequested = true
|
||||
this.materializationRetryAbortController?.abort()
|
||||
await this.waitForPromise(materializationTask, remainingMs())
|
||||
if (!await this.waitForPromise(materializationTask, remainingMs())) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (this.state !== 'active') {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
if (!this.socket.connected) {
|
||||
const connected = await this.waitForConnected(remainingMs())
|
||||
if (!connected) {
|
||||
return
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
await this.drainLock(this.metadataLock, remainingMs())
|
||||
await this.drainLock(this.agentStateLock, remainingMs())
|
||||
if (!await this.drainLock(this.metadataLock, remainingMs())) {
|
||||
return false
|
||||
}
|
||||
if (!await this.drainLock(this.agentStateLock, remainingMs())) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (remainingMs() === 0) {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
const pingTimeoutMs = remainingMs()
|
||||
if (pingTimeoutMs === 0) {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
await this.socket.timeout(pingTimeoutMs).emitWithAck('ping')
|
||||
this.awaitingMaterializedConnection = false
|
||||
return true
|
||||
} catch {
|
||||
// best effort
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user