Motivation
The default store is filesystem-backed, giving crash-safe at-most-once semantics on a single host. Operators running the same job from multiple hosts/containers (HA schedulers, k8s CronJobs with >1 replica) need a shared marker store so the effect is deduplicated across hosts.
Proposal
Extract a Backend interface so the lock/marker store is pluggable, and ship adapters:
RedisBackend — SET key val NX PX <lease> for the lock; marker in a hash.
SqliteBackend — single-table marker store with a transaction-guarded acquire.
interface Backend {
readMarker(key: string): Promise<Marker | null>;
writeMarker(key: string, marker: Marker): Promise<void>;
acquireLock(key: string, leaseMs: number): Promise<boolean>;
releaseLock(key: string): Promise<void>;
}
createOnceStore({ backend: new RedisBackend(client) });
Acceptance
Motivation
The default store is filesystem-backed, giving crash-safe at-most-once semantics on a single host. Operators running the same job from multiple hosts/containers (HA schedulers, k8s CronJobs with >1 replica) need a shared marker store so the effect is deduplicated across hosts.
Proposal
Extract a
Backendinterface so the lock/marker store is pluggable, and ship adapters:RedisBackend—SET key val NX PX <lease>for the lock; marker in a hash.SqliteBackend— single-table marker store with a transaction-guarded acquire.Acceptance
Backendinterface extracted; current fs logic becomes the defaultFsBackend.