| 110 | * a real reboot. Throws if it never goes down within the deadline. |
| 111 | */ |
| 112 | export const waitForHttpDown = async ( |
| 113 | url: string, |
| 114 | options: { readonly timeoutMs?: number } = {}, |
| 115 | ): Promise<void> => { |
| 116 | const deadline = Date.now() + (options.timeoutMs ?? 120_000); |
| 117 | while (Date.now() < deadline) { |
| 118 | try { |
| 119 | await fetch(url, { redirect: "manual", signal: AbortSignal.timeout(2000) }); |
| 120 | } catch { |
| 121 | return; // the server (or its tunnel) is gone — the reboot took |
| 122 | } |
| 123 | await new Promise((resolve) => setTimeout(resolve, 500)); |
| 124 | } |
| 125 | throw new Error(`${url} never became unreachable — the reboot may not have taken`); |
| 126 | }; |