Retry an async init call with exponential backoff + jitter.
( fn: () => Promise<T | null>, label: string, cfg: EnvLessBridgeConfig, )
| 890 | |
| 891 | /** Retry an async init call with exponential backoff + jitter. */ |
| 892 | async function withRetry<T>( |
| 893 | fn: () => Promise<T | null>, |
| 894 | label: string, |
| 895 | cfg: EnvLessBridgeConfig, |
| 896 | ): Promise<T | null> { |
| 897 | const max = cfg.init_retry_max_attempts |
| 898 | for (let attempt = 1; attempt <= max; attempt++) { |
| 899 | const result = await fn() |
| 900 | if (result !== null) return result |
| 901 | if (attempt < max) { |
| 902 | const base = cfg.init_retry_base_delay_ms * 2 ** (attempt - 1) |
| 903 | const jitter = |
| 904 | base * cfg.init_retry_jitter_fraction * (2 * Math.random() - 1) |
| 905 | const delay = Math.min(base + jitter, cfg.init_retry_max_delay_ms) |
| 906 | logForDebugging( |
| 907 | `[remote-bridge] ${label} failed (attempt ${attempt}/${max}), retrying in ${Math.round(delay)}ms`, |
| 908 | ) |
| 909 | await sleep(delay) |
| 910 | } |
| 911 | } |
| 912 | return null |
| 913 | } |
| 914 | |
| 915 | // Moved to codeSessionApi.ts so the SDK /bridge subpath can bundle them |
| 916 | // without pulling in this file's heavy CLI tree (analytics, transport). |
no test coverage detected