diff --git a/src/cron/service/store.ts b/src/cron/service/store.ts index 9b99a99dd822..2944d6a33501 100644 --- a/src/cron/service/store.ts +++ b/src/cron/service/store.ts @@ -11,7 +11,10 @@ import { saveCronJobsStore, type QuarantinedCronConfigJob, } from "../store.js"; -import type { CronStoreTransactionHooks } from "../store/transaction-hooks.js"; +import { + type CronStoreTransactionHooks, + saveCronJobsStoreWithTransactionHooks, +} from "../store/transaction-hooks.js"; import type { CronJob, CronStoreFile } from "../types.js"; import { computeJobNextRunAtMs, recomputeNextRuns } from "./jobs-scheduling.js"; import { assertTimeScheduleSatisfiable } from "./jobs-validation.js"; @@ -281,17 +284,17 @@ export async function persist(state: CronServiceState, opts?: PersistOptions) { : undefined; const stateOnly = !quarantine && opts?.stateOnly === true; try { - await saveCronJobsStore( - state.deps.storePath, - store, - quarantine - ? { quarantine, transactionHooks: opts?.transactionHooks } - : stateOnly - ? { stateOnly: true, transactionHooks: opts?.transactionHooks } - : opts?.transactionHooks - ? { transactionHooks: opts.transactionHooks } - : undefined, - ); + const saveOptions = quarantine ? { quarantine } : stateOnly ? { stateOnly: true } : undefined; + if (opts?.transactionHooks) { + await saveCronJobsStoreWithTransactionHooks( + state.deps.storePath, + store, + saveOptions, + opts.transactionHooks, + ); + } else { + await saveCronJobsStore(state.deps.storePath, store, saveOptions); + } } catch (error) { if (!quarantine) { throw error; diff --git a/src/cron/store.ts b/src/cron/store.ts index 3ef9c9661d3b..ba429b93eb56 100644 --- a/src/cron/store.ts +++ b/src/cron/store.ts @@ -242,6 +242,9 @@ type SaveCronJobsStoreOptions = SaveCronStoreOptions & { entries: readonly (QuarantinedCronConfigJob | CronQuarantinedJob)[]; nowMs: number; }; +}; + +type SaveCronJobsStoreInternalOptions = SaveCronJobsStoreOptions & { transactionHooks?: CronStoreTransactionHooks; }; @@ -250,7 +253,12 @@ export async function saveCronJobsStore( storePath: string, store: CronStoreFile, opts?: SaveCronJobsStoreOptions, -) { +): Promise; +export async function saveCronJobsStore( + storePath: string, + store: CronStoreFile, + opts?: SaveCronJobsStoreInternalOptions, +): Promise { const resolvedStorePath = path.resolve(storePath); const storeKey = cronStoreKey(resolvedStorePath); const stateOnly = opts?.stateOnly === true && !opts.quarantine?.entries.length; diff --git a/src/cron/store/transaction-hooks.ts b/src/cron/store/transaction-hooks.ts index ac426a782cba..55915474887a 100644 --- a/src/cron/store/transaction-hooks.ts +++ b/src/cron/store/transaction-hooks.ts @@ -1,6 +1,27 @@ import type { DatabaseSync } from "node:sqlite"; +import { saveCronJobsStore } from "../store.js"; +import type { CronStoreFile } from "../types.js"; export type CronStoreTransactionHooks = { beforeWrite?: (db: DatabaseSync) => void; afterWrite?: (db: DatabaseSync) => void; }; + +type SaveCronJobsStoreOptions = NonNullable[2]>; +type InternalSaveCronJobsStore = ( + storePath: string, + store: CronStoreFile, + opts: SaveCronJobsStoreOptions & { transactionHooks: CronStoreTransactionHooks }, +) => Promise; + +export async function saveCronJobsStoreWithTransactionHooks( + storePath: string, + store: CronStoreFile, + opts: SaveCronJobsStoreOptions | undefined, + transactionHooks: CronStoreTransactionHooks, +): Promise { + await (saveCronJobsStore as InternalSaveCronJobsStore)(storePath, store, { + ...opts, + transactionHooks, + }); +}