@cavai/adonis-queue
Version:
Basic AdonisJS queue provider
97 lines (96 loc) • 2.86 kB
JavaScript
import { DateTime } from 'luxon';
import SuperJSON from 'superjson';
export default class DatabaseDriver {
config;
#trx;
#database;
pollingDelay;
constructor(config, database) {
this.config = config;
this.pollingDelay = config.pollingDelay || 2000;
this.#database = database;
}
/**
* Store job to database
*/
async store(path, payload, options) {
const job = await this.#database
.table(this.config.tableName)
.insert({
class_path: path,
payload: SuperJSON.serialize(payload),
available_at: options?.availableAt || DateTime.now().toSQL({ includeOffset: false }),
})
.returning('id');
return {
id: job[0].id,
};
}
/**
* Get next job from database
*/
async getNext() {
this.#trx = await this.#database.transaction();
const job = await this.#trx
.from(this.config.tableName)
.where('available_at', '<', DateTime.now().toSQL({ includeOffset: false }))
.where({ failed: false })
.forUpdate()
.skipLocked()
.first();
if (!job) {
await this.#trx.commit();
return null;
}
return job;
}
/**
* Get job from database by its ID
*/
getJob(id) {
return this.#database
.from(this.config.tableName)
.where('available_at', '<', DateTime.now().toSQL({ includeOffset: false }))
.where({ id: id })
.first();
}
/**
* Re-schedule job (update attempts and available_at) in Database
*/
async reSchedule(job, retryAfter) {
if (!this.#trx) {
throw new Error('Cannot reschedule job without an active transaction');
}
await this.#trx
.from(this.config.tableName)
.where({ id: job.id })
.update({
attempts: job.attempts + 1,
available_at: DateTime.now().plus({ seconds: retryAfter }),
});
await this.#trx.commit();
}
/**
* Mark job as failed in database
*/
async markFailed(job) {
if (!this.#trx) {
throw new Error('Cannot mark job as failed without an active transaction');
}
await this.#trx.from(this.config.tableName).where({ id: job.id }).update({
failed: true,
attempts: job.attempts,
});
await this.#trx.commit();
}
/**
* Remove job from database
*/
async remove(id) {
if (!this.#trx) {
throw new Error('Cannot remove job without an active transaction');
}
await this.#trx.from(this.config.tableName).where({ id: id }).delete();
await this.#trx.commit();
}
}