Skip to content

src/ingest-shas.ts

51 lines · 1.4 KB · TypeScript
Raw
export type ShaIngestError = { sha: string; error: string }

export type IngestShasResult = {
	ingested: string[]
	alreadyStored: string[]
	errors: ShaIngestError[]
	remaining: number
}

/**
 * Ingest an explicit SHA list (from a push webhook) without letting one failed
 * commit fetch fail the whole delivery. Failed SHAs are reported in `errors`;
 * the `backfill-missing` job picks them up on its next tick.
 */
export async function ingestShaList(
	shas: string[],
	deps: {
		deadline: number
		hasCommit: (sha: string) => Promise<boolean>
		ingest: (sha: string) => Promise<unknown>
		now?: () => number
		warn?: (message: string) => void
	},
): Promise<IngestShasResult> {
	const now = deps.now ?? Date.now
	const warn = deps.warn ?? ((message: string) => console.warn(message))
	const ingested: string[] = []
	const alreadyStored: string[] = []
	const errors: ShaIngestError[] = []
	for (const sha of shas) {
		if (now() >= deps.deadline) break
		if (await deps.hasCommit(sha)) {
			alreadyStored.push(sha)
			continue
		}
		try {
			await deps.ingest(sha)
			ingested.push(sha)
		} catch (error) {
			const message = error instanceof Error ? error.message : String(error)
			errors.push({ sha, error: message })
			warn(`lineage: deferred ${sha} to backfill-missing: ${message}`)
		}
	}
	return {
		ingested,
		alreadyStored,
		errors,
		remaining: shas.length - ingested.length - alreadyStored.length,
	}
}