()
| 392 | } |
| 393 | |
| 394 | async restart(): Promise<void> { |
| 395 | if (this.restarting) { |
| 396 | console.log(`[guardian] UTA restart already in progress, skipping`) |
| 397 | return |
| 398 | } |
| 399 | this.restarting = true |
| 400 | try { |
| 401 | console.log(`[guardian] restarting UTA`) |
| 402 | const old = this.child |
| 403 | this.cascade?.expectExit(old) |
| 404 | const exited = new Promise<void>((resolve) => old.once('exit', () => resolve())) |
| 405 | killTree(old, 'SIGTERM') |
| 406 | await Promise.race([exited, sleep(8_000)]) |
| 407 | if (old.exitCode === null) { |
| 408 | killTree(old, 'SIGKILL') |
| 409 | await exited |
| 410 | } |
| 411 | |
| 412 | const next = spawnChild(this.spec) |
| 413 | this.child = next |
| 414 | this.cascade?.trackReplacement(old, next) |
| 415 | |
| 416 | const ready = await waitForHttp(this.healthUrl, { timeoutMs: 15_000 }) |
| 417 | if (!ready) { |
| 418 | console.error(`[guardian] UTA failed to come back up after restart`) |
| 419 | return |
| 420 | } |
| 421 | console.log(`[guardian] UTA back online`) |
| 422 | } finally { |
| 423 | this.restarting = false |
| 424 | } |
| 425 | } |
| 426 | } |
| 427 | |
| 428 | // ==================== restart-flag watcher ==================== |
no test coverage detected