UNPKG

@backgroundjs/core

Version:

An extendible background job queue for js/ts applications

147 lines 4.85 kB
/** * MongoDB storage adapter for JobQueue * * This storage adapter uses MongoDB to store jobs, making it suitable * for distributed environments with multiple instances/processes. * * Note: You must install the 'mongodb' package to use this adapter: * npm install mongodb */ export class MongoDBJobStorage { constructor(mongoClient, options = {}) { this.logging = false; this.staleJobTimeout = 1000 * 60 * 60 * 24; // 24 hours this.mongoClient = mongoClient; this.collection = this.mongoClient .db() .collection(options.collectionName || "jobs"); this.logging = options.logging || false; this.staleJobTimeout = options.staleJobTimeout || 1000 * 60 * 60 * 24; // 24 hours } /** * Save a job * @param job - The job to save */ async saveJob(job) { try { await this.collection.insertOne(job); } catch (error) { if (this.logging) { console.error("Error saving job", error); } } } /** * Get a job by ID * @param id - The ID of the job to get * @returns The job with the given ID, or null if the job does not exist */ async getJob(id) { try { return await this.collection.findOne({ id }); } catch (error) { if (this.logging) { console.error("Error getting job", error); } return null; } } /** * Get all jobs by status * @param status - The status of the jobs to get * @returns An array of jobs with the given status */ async getJobsByStatus(status) { try { return await this.collection.find({ status }).toArray(); } catch (error) { if (this.logging) { console.error("Error getting jobs by status", error); } return []; } } /** * Update a job * @param job - The job to update * @throws Error if the job is not found */ async updateJob(job) { try { await this.collection.findOneAndUpdate({ id: job.id }, { $set: job }); } catch (error) { if (this.logging) { console.error("Error updating job", error); } } } /** * Acquire the next pending job * @returns The next pending job, or null if no pending jobs are available */ async acquireNextJob() { try { const staleThreshold = new Date(Date.now() - this.staleJobTimeout); // First try to find pending jobs let job = await this.collection.findOneAndUpdate({ status: "pending", $or: [ { scheduledAt: { $exists: false } }, { scheduledAt: { $lte: new Date() } }, ], }, { $set: { status: "processing", startedAt: new Date() } }, { sort: { priority: 1, createdAt: 1 }, returnDocument: "after" }); if (!job) { job = await this.collection.findOneAndUpdate({ status: "processing", startedAt: { $lte: staleThreshold }, $or: [ { completedAt: { $exists: false } }, { completedAt: null } ] }, { $set: { startedAt: new Date() } }, { sort: { priority: 1, createdAt: 1 }, returnDocument: "after" }); } return job; } catch (error) { if (this.logging) { console.error(`[MongoDBJobStorage] Error acquiring next job:`, error); } return null; } } /** * Complete a job * @param jobId - The ID of the job to complete * @param result - The result of the job */ async completeJob(jobId, result) { try { await this.collection.findOneAndUpdate({ id: jobId, status: "processing" }, { $set: { status: "completed", result, completedAt: new Date() } }); } catch (error) { if (this.logging) { console.error(`[MongoDBJobStorage] Error completing job:`, error); } } } /** * Fail a job * @param jobId - The ID of the job to fail * @param error - The error message */ async failJob(jobId, error) { try { await this.collection.findOneAndUpdate({ id: jobId, status: "processing" }, { $set: { status: "failed", error, completedAt: new Date() } }); } catch (error) { if (this.logging) { console.error(`[MongoDBJobStorage] Error failing job:`, error); } } } } //# sourceMappingURL=mongodb-storage.js.map