Skip to content

Commit c96fed1

Browse files
committed
Terminate Gateway child when liveness fails in error state
If refreshStatus finds the process retained but not live after a pairing error, tear it down so Stop is not stuck disabled and Start cannot spawn a second child.
1 parent fa67413 commit c96fed1

1 file changed

Lines changed: 16 additions & 5 deletions

File tree

Sources/VocaMac/Services/GatewayEmbedController.swift

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ final class GatewayEmbedController: ObservableObject {
215215
return
216216
}
217217

218+
// Never stack a second child on a retained process that is no longer live.
219+
if process != nil {
220+
await terminateSpawnedProcess()
221+
}
222+
218223
status = .starting
219224
lastErrorMessage = nil
220225
pairingPayload = nil
@@ -259,26 +264,32 @@ final class GatewayEmbedController: ObservableObject {
259264

260265
let live = await probe(path: "/")
261266
let ready = await probe(path: "/health/ready")
262-
isLive = live
263-
isReady = ready
264267

265268
if !live {
266269
pairingPayload = nil
267270
pairingPayloadRaw = nil
271+
if process != nil, case .error = status {
272+
// Reap a retained child so Stop is not disabled while it is still running.
273+
await terminateSpawnedProcess()
274+
return
275+
}
268276
if process?.isRunning == true {
269-
if case .error = status {
270-
return
271-
}
277+
isLive = false
278+
isReady = false
272279
status = .starting
273280
return
274281
}
282+
isLive = false
283+
isReady = false
275284
if case .error = status {
276285
return
277286
}
278287
status = .stopped
279288
return
280289
}
281290

291+
isLive = true
292+
isReady = ready
282293
await fetchPairing()
283294
}
284295

0 commit comments

Comments
 (0)