UNPKG

@timecrisis/timecrisis-sqlite

Version:

A SQLite storage adapter for the Time Crisis job scheduler

310 lines (307 loc) 11.9 kB
import { Database } from 'better-sqlite3'; import { JobStorage, CreateJob, Job, UpdateJob, CreateJobRun, UpdateJobRun, JobRun, CreateJobLog, JobLogEntry, CreateScheduledJob, UpdateScheduledJob, ScheduledJob, CreateDeadLetterJob, DeadLetterJob, JobStorageMetrics, RegisterWorker, UpdateWorkerHeartbeat, Worker } from '@timecrisis/timecrisis'; /** * SQLite storage adapter that implements the JobStorage interface. * This storage provider uses SQLite as the backing store. */ declare class SQLiteJobStorage implements JobStorage { /** * The SQLite database instance used for all operations */ private db; /** * Prepared statements. */ private stmtInsertJob; private stmtSelectJobById; private stmtUpdateJob; private stmtDeleteJob; private stmtSelectFilteredJobs; private stmtInsertJobRun; private stmtSelectJobRunById; private stmtUpdateJobRun; private stmtSelectJobRunsByJobId; private stmtDeleteJobRunsByJobId; private stmtInsertJobLog; private stmtSelectJobLogsByJobId; private stmtSelectJobLogsByJobAndRun; private stmtDeleteJobLogsByJobId; private stmtInsertScheduledJob; private stmtSelectScheduledJobById; private stmtUpdateScheduledJob; private stmtSelectAllScheduledJobs; private stmtSelectFilteredScheduledJobs; private stmtInsertDeadLetterJob; private stmtSelectAllDeadLetterJobs; private stmtDeleteDeadLetterBefore; private stmtListLocks; private stmtInsertLock; private stmtUpdateLock; private stmtDeleteLock; private stmtCleanupCompleted; private stmtCleanupFailed; private stmtJobCounts; private stmtAvgDuration; private stmtFailureRate; private stmtInsertTypeSlot; private stmtDecrementTypeSlot; private stmtDeleteEmptyTypeSlots; private stmtDeleteWorkerTypeSlots; private stmtGetTotalRunningJobs; private stmtGetTotalRunningJobsByType; private stmtInsertWorker; private stmtUpdateWorkerHeartbeat; private stmtSelectWorkerByName; private stmtSelectInactiveWorkers; private stmtSelectAllWorkers; private stmtDeleteWorker; constructor(db: Database); /** * Initialize the SQLite storage provider * This will run any pending migrations and prepare all SQL statements * for improved performance */ init({ runMigrations }?: { runMigrations?: boolean; }): Promise<void>; /** * Close the database connection and clean up resources * This should be called when the storage provider is no longer needed */ close(): Promise<void>; /** * Execute a function within a transaction * This ensures ACID properties for all operations within the transaction * @param fn - Function to execute within the transaction * @returns Promise resolving to the function's result */ transaction<T>(fn: (trx: unknown) => T): Promise<T>; /** * Create a new job in the database * @param job - Job data to create * @returns Unique identifier of the created job */ createJob(job: CreateJob): Promise<string>; /** * Retrieve a job by its unique identifier * @param id - Unique identifier of the job to retrieve * @returns Job data or null if not found */ getJob(id: string): Promise<Job | undefined>; /** * Update an existing job with new data * @param id - Unique identifier of the job to update * @param updates - Updated job data */ updateJob(id: string, updates: UpdateJob): Promise<void>; /** * Create a new job run for an existing job * @param jobRun - Job run data to create * @returns Unique identifier of the created job run */ createJobRun(jobRun: CreateJobRun): Promise<string>; /** * Update an existing job run with new data * @param id - Unique identifier of the job run to update * @param updates - Updated job run data */ updateJobRun(id: string, updates: UpdateJobRun): Promise<void>; /** * Retrieve a job run by its unique identifier * @param id - Unique identifier of the job run to retrieve * @returns Job run data or undefined if not found */ getJobRun(id: string): Promise<JobRun | undefined>; /** * List job runs for a specific job * @param jobId - Unique identifier of the job * @returns Array of job runs for the specified job */ listJobRuns(jobId: string): Promise<JobRun[]>; /** * List jobs based on the provided filter criteria * @param filter - Filter criteria (optional) * @returns Array of jobs matching the filter criteria */ listJobs(filter?: { status?: string[]; type?: string; referenceId?: string; runAtBefore?: Date; limit?: number; expiresAtBefore?: Date; }): Promise<Job[]>; /** * Create a new log entry for a job run * @param log - Log entry data to create */ createJobLog(log: CreateJobLog): Promise<void>; /** * List log entries for a specific job run * @param jobId - Unique identifier of the job * @param runId - Unique identifier of the job run (optional) * @returns Array of log entries for the specified job run */ listJobLogs(jobId: string, runId?: string): Promise<JobLogEntry[]>; /** * Create a new scheduled job * @param job - Scheduled job data to create * @returns Unique identifier of the created scheduled job */ createScheduledJob(job: CreateScheduledJob): Promise<string>; /** * Update an existing scheduled job with new data * @param id - Unique identifier of the scheduled job to update * @param updates - Updated scheduled job data */ updateScheduledJob(id: string, updates: UpdateScheduledJob): Promise<void>; /** * Retrieve a scheduled job by its unique identifier * @param id - Unique identifier of the scheduled job to retrieve * @returns Scheduled job data or null if not found */ getScheduledJob(id: string): Promise<ScheduledJob | null>; /** * List scheduled jobs based on the provided filter criteria * @param filter - Filter criteria (optional) * @returns Array of scheduled jobs matching the filter criteria */ listScheduledJobs(filter?: { enabled?: boolean; nextRunBefore?: Date; referenceId?: string; }): Promise<ScheduledJob[]>; /** * Create a new dead letter job * @param job - Dead letter job data to create */ createDeadLetterJob(job: CreateDeadLetterJob): Promise<void>; /** * List dead letter jobs * @returns Array of dead letter jobs */ listDeadLetterJobs(): Promise<DeadLetterJob[]>; /** * Acquire a lock for a specific job * @param lockId - Unique identifier of the lock * @param worker - Identifier of the lock worker * @param ttlMs - Time to live for the lock (in milliseconds) * @returns True if the lock was acquired, false otherwise */ acquireLock(lockId: string, worker: string, ttlMs: number): Promise<boolean>; /** * Renew an existing lock for a specific job * @param lockId - Unique identifier of the lock * @param worker - Identifier of the lock worker * @param ttlMs - Time to live for the lock (in milliseconds) * @returns True if the lock was renewed, false otherwise */ renewLock(lockId: string, worker: string, ttlMs: number): Promise<boolean>; /** * Release a lock. * @param lockId - Unique identifier of the lock * @param worker - Identifier of the lock worker * @returns True if the lock was released, false otherwise */ releaseLock(lockId: string, worker: string): Promise<boolean>; /** * List all locks owned by a specific worker. * @returns An array of objects with lock details, each containing lockId, worker, and expiresAt */ listLocks(filters?: { worker?: string; expiredBefore?: Date; }): Promise<{ lockId: string; worker: string; expiresAt: Date; }[]>; /** * Clean up jobs and related data based on the provided retention periods * @param options - Retention periods for jobs, failed jobs, and dead letter jobs */ cleanup(options: { jobRetention: number; failedJobRetention: number; deadLetterRetention: number; }): Promise<void>; /** * Delete a job and its related data (runs, logs) * @param jobId - Unique identifier of the job to delete */ deleteJobAndRelatedData(jobId: string): Promise<void>; /** * Get storage metrics including job counts and performance metrics * @returns Storage metrics */ getMetrics(): Promise<JobStorageMetrics>; /** * Acquire a slot for a specific job type and worker * @param jobType - The type of the job * @param worker - The ID of the worker requesting the slot * @param maxConcurrent - Maximum allowed concurrent jobs for this type * @returns True if the slot was acquired, false otherwise */ acquireTypeSlot(jobType: string, worker: string, maxConcurrent: number): Promise<boolean>; /** * Release a slot for a specific job type and worker * @param jobType - The type of the job * @param worker - The worker releasing the slot */ releaseTypeSlot(jobType: string, worker: string): Promise<void>; /** * Release all slots held by a specific worker * @param worker - The worker to release all slots for */ releaseAllTypeSlots(worker: string): Promise<void>; /** * Get the current running count for a specific job type or total across all types * @param jobType - Optional, the type of the job to count. If not provided, returns total across all types * @returns Number of currently running jobs */ getRunningCount(jobType?: string): Promise<number>; /** * Register a new worker instance in the system * @param worker - Worker registration data containing the worker name * @returns Promise that resolves with the ID of the registered worker * @throws ZodError if the worker registration data is invalid */ registerWorker(worker: RegisterWorker): Promise<string>; /** * Update a worker's heartbeat timestamp * @param workerName - Name of the worker to update * @param heartbeat - Heartbeat data containing the new timestamp * @throws WorkerNotFoundError if the worker doesn't exist * @throws ZodError if the heartbeat data is invalid */ updateWorkerHeartbeat(workerName: string, heartbeat: UpdateWorkerHeartbeat): Promise<void>; /** * Get a worker by its name * @param workerName - Name of the worker to retrieve * @returns Promise that resolves with the worker data or null if not found */ getWorker(workerName: string): Promise<Worker | null>; /** * Get all workers that haven't sent a heartbeat since the specified time * @param lastHeartbeatBefore - Time threshold for considering workers inactive * @returns Promise that resolves with an array of inactive workers */ getInactiveWorkers(lastHeartbeatBefore: Date): Promise<Worker[]>; /** * Get all registered workers in the system * @returns Promise that resolves with an array of all workers */ getWorkers(): Promise<Worker[]>; /** * Delete a worker by its name * @param workerName - Name of the worker to delete * @throws WorkerNotFoundError if the worker doesn't exist */ deleteWorker(workerName: string): Promise<void>; private mapRowToLock; private mapRowToJob; private mapRowToJobRun; private mapRowToJobLog; private mapRowToScheduledJob; } export { SQLiteJobStorage };