@cortexql/queue
Version:
An extension for Queue implementation on CortexQL based on Bull Queue
154 lines • 5.17 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const Bull = require("bull");
const cluster = require("cluster");
const core_1 = require("@cortexql/core");
class QueueClient {
constructor(queue) {
this.queue = queue;
this.bullQueue = new Bull(queue.name, queue.options);
}
/**
* Returns a promise that resolves when Redis is connected and the queue is ready to accept jobs.
* This replaces the `ready` event emitted on Queue in previous verisons.
*/
isReady() {
return __awaiter(this, void 0, void 0, function* () {
yield this.bullQueue.isReady();
return this;
});
}
get(id) {
return __awaiter(this, void 0, void 0, function* () {
return this.bullQueue.getJob(id);
});
}
dispatch(...args) {
return __awaiter(this, void 0, void 0, function* () {
return yield this.bullQueue.add(...args);
});
}
isWorker() {
return false;
}
close() {
return __awaiter(this, void 0, void 0, function* () {
try {
return yield this.bullQueue.close();
}
catch (error) {
throw error;
}
});
}
}
exports.QueueClient = QueueClient;
class QueueWorkerClient extends QueueClient {
constructor(queue, concurrency = 1) {
super(queue);
this.queue = queue;
if (queue.handler == null) {
throw new Error(`A process handler must be specified`);
}
workerQueues.push(this);
this.bullQueue.process(concurrency, (job) => __awaiter(this, void 0, void 0, function* () {
let context;
try {
context = yield queue.createContext(job);
const result = yield queue.handler(job, context, this);
if (!context.completed) {
context.end();
}
return result;
}
catch (error) {
console.log(error.stack);
setTimeout(() => {
if (typeof context !== 'undefined' && !context.completed) {
context.end(error);
}
}, 100);
throw error;
}
}));
}
isWorker() {
return true;
}
}
exports.QueueWorkerClient = QueueWorkerClient;
class Queue {
constructor(name, options) {
this.name = name;
this.options = options;
this.debug = core_1.debug(`queue:${this.name}`);
}
contextParams(handler) {
this.contextParamsHandler = handler;
}
getContextParams(job) {
const contextParams = this.contextParamsHandler;
if (typeof contextParams === 'undefined') {
return {};
}
if (typeof contextParams === 'function') {
return contextParams(job);
}
return contextParams;
}
createContext(job) {
return core_1.createContext(this.getContextParams(job), this.name, 'queue', job.id);
}
process(handler) {
if (this.handler != null) {
throw new Error(`A process handler was already specified`);
}
this.handler = handler;
}
worker(concurrency = 1) {
return __awaiter(this, void 0, void 0, function* () {
return new QueueWorkerClient(this, concurrency);
});
}
createClient() {
return new QueueClient(this);
}
subscribe() {
return __awaiter(this, void 0, void 0, function* () {
return this.createClient();
});
}
start(concurrency = 1, workers = 1) {
if (workers > 0 && concurrency > 0) {
core_1.hooks.init.addAction(`${this.name}Queue`, () => {
if (cluster.isMaster) {
console.log(`Started "${this.name}" Queue with ${workers}x${concurrency}`);
}
if (cluster.isMaster && workers > 1) {
for (let i = 0; i < workers; i++) {
cluster.fork();
}
}
else if (concurrency > 0) {
this.worker(concurrency)
.catch(error => console.log(error.stack));
}
});
}
}
}
exports.Queue = Queue;
const workerQueues = [];
function getWorkerQueues() {
return [...workerQueues];
}
exports.getWorkerQueues = getWorkerQueues;
//# sourceMappingURL=Queue.js.map