diff --git a/packages/daemon/src/util/tryFetch.ts b/packages/daemon/src/util/tryFetch.ts index 04720b4f..52898bc7 100644 --- a/packages/daemon/src/util/tryFetch.ts +++ b/packages/daemon/src/util/tryFetch.ts @@ -1,50 +1,64 @@ import { LoggerService } from '@pockethost/common' -import fetch from 'node-fetch' -import { AsyncContext } from './AsyncContext' +import fetch, { Response } from 'node-fetch' export const TRYFETCH_RETRY_MS = 50 -export type Config = Required & { +export type Config = { preflight: () => Promise retryMs: number } +/** + * + * @param url The URL to fetch + * @param config { preflight: ()=>Promise, retryMs: number} + * @returns Promise + * + * tryFetch will contiously try to fetch a URL every `retryMs`, with an optinoal `preflight`. + * If `preflight` is specificed, it must resolve to `true` before tryFetch + * will attempt to fetch the URL. If `preflight` resolves to `false`, tryFetch + * will delay by `retryMs` and then check again. If `preflight` rejects, + * then tryFetch rejects and exits. + * + * Note: tryFetch exits ONLY on success or a rejected preflight. + */ export const tryFetch = async (url: string, config?: Partial) => { - const { logger, preflight, retryMs }: Config = { - logger: LoggerService().create(`tryFetch`), + const { preflight, retryMs }: Config = { preflight: async () => true, retryMs: TRYFETCH_RETRY_MS, ...config, } - const _logger = logger.create(`tryFetch`) - const { dbg } = _logger - return new Promise((resolve, reject) => { - const tryFetch = async () => { + const logger = LoggerService().create(`tryFetch`).breadcrumb(url) + const { dbg } = logger + return new Promise((resolve, reject) => { + const again = () => setTimeout(_real_tryFetch, retryMs) + const _real_tryFetch = async () => { if (preflight) { - dbg(`Checking preflight`) try { + dbg(`Preflight: CHECK`) const shouldFetch = await preflight() if (!shouldFetch) { - reject(new Error(`failed preflight, aborting`)) + dbg(`Preflight: NOT READY`) + again() return } + dbg(`Preflight: READY`) } catch (e) { - reject(new Error(`preflight threw error, aborting`)) + dbg(`Preflight: ABORT`) + reject(e) return } } try { - dbg(`Trying to fetch ${url} `) + dbg(`Fetch: START`) const res = await fetch(url) - dbg(`Fetch ${url} successful`) - resolve() + dbg(`Fetch: SUCCESS`) + resolve(res) } catch (e) { - dbg( - `Could not fetch ${url}, trying again in ${retryMs}ms. Raw error ${e}`, - ) - setTimeout(tryFetch, retryMs) + dbg(`Fetch: ERROR: trying again in ${retryMs}ms | ${e}`) + again() } } - tryFetch() + _real_tryFetch() }) }