@timecrisis/timecrisis-sqlite
Version:
A SQLite storage adapter for the Time Crisis job scheduler
310 lines (307 loc) • 11.9 kB
TypeScript
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 };