@tryghost/job-manager: Switch to @tryghost/logging from injected argument

refs: https://github.com/TryGhost/Toolbox/issues/146
This commit is contained in:
Sam Lord 2021-12-02 12:48:48 +00:00
parent cd9e295ec8
commit a98ae3734f
3 changed files with 34 additions and 32 deletions

View File

@ -4,6 +4,7 @@ const later = require('@breejs/later');
const Bree = require('bree');
const pWaitFor = require('p-wait-for');
const {UnhandledJobError, IncorrectUsageError} = require('@tryghost/errors');
const logging = require('@tryghost/logging');
const isCronExpression = require('./is-cron-expression');
const assembleBreeJob = require('./assemble-bree-job');
@ -28,11 +29,10 @@ const handler = (error, result) => {
class JobManager {
/**
* @param {Object} options
* @param {Object} [options.logging] - custom logging handler, defaults to console
* @param {Function} [options.errorHandler] - custom job error handler
* @param {Function} [options.workerMessageHandler] - custom message handler coming from workers
*/
constructor({logging, errorHandler, workerMessageHandler}) {
constructor({errorHandler, workerMessageHandler}) {
this.queue = fastq(this, worker, 1);
this.bree = new Bree({
@ -43,8 +43,6 @@ class JobManager {
errorHandler: errorHandler,
workerMessageHandler: workerMessageHandler
});
this.logging = logging;
}
/**
@ -60,7 +58,7 @@ class JobManager {
*/
addJob({name, at, job, data, offloaded = true}) {
if (offloaded) {
this.logging.info('Adding offloaded job to the queue');
logging.info('Adding offloaded job to the queue');
let schedule;
if (!name) {
@ -86,18 +84,18 @@ class JobManager {
});
}
this.logging.info(`Scheduling job ${name} at ${at}. Next run on: ${later.schedule(schedule).next()}`);
logging.info(`Scheduling job ${name} at ${at}. Next run on: ${later.schedule(schedule).next()}`);
} else if (at !== undefined) {
this.logging.info(`Scheduling job ${name} at ${at}`);
logging.info(`Scheduling job ${name} at ${at}`);
} else {
this.logging.info(`Scheduling job ${name} to run immediately`);
logging.info(`Scheduling job ${name} to run immediately`);
}
const breeJob = assembleBreeJob(at, job, data, name);
this.bree.add(breeJob);
return this.bree.start(name);
} else {
this.logging.info('Adding one off inline job to the queue');
logging.info('Adding one off inline job to the queue');
this.queue.push(async () => {
try {
@ -109,7 +107,7 @@ class JobManager {
} catch (err) {
// NOTE: each job should be written in a safe way and handle all errors internally
// if the error is caught here jobs implementaton should be changed
this.logging.error(new UnhandledJobError({
logging.error(new UnhandledJobError({
context: (typeof job === 'function') ? 'function' : job,
err
}));
@ -144,11 +142,11 @@ class JobManager {
return;
}
this.logging.warn('Waiting for busy job queue');
logging.warn('Waiting for busy job queue');
await pWaitFor(() => this.queue.idle() === true, options);
this.logging.warn('Job queue finished');
logging.warn('Job queue finished');
}
}

View File

@ -29,6 +29,7 @@
},
"dependencies": {
"@breejs/later": "^4.0.2",
"@tryghost/logging": "^1.0.2",
"bree": "^6.2.0",
"cron-validate": "^1.4.3",
"fastq": "^1.11.0",

View File

@ -5,22 +5,25 @@ const path = require('path');
const sinon = require('sinon');
const delay = require('delay');
const FakeTimers = require('@sinonjs/fake-timers');
const logging = require('@tryghost/logging');
const JobManager = require('../index');
describe('Job Manager', function () {
let logging;
const sandbox = sinon.createSandbox();
describe('Job Manager', function () {
beforeEach(function () {
logging = {
info: sinon.stub(),
warn: sinon.stub(),
error: sinon.stub()
};
sandbox.stub(logging, 'info');
sandbox.stub(logging, 'warn');
sandbox.stub(logging, 'error');
});
afterEach(function () {
sandbox.restore();
});
it('public interface', function () {
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
should.exist(jobManager.addJob);
});
@ -29,7 +32,7 @@ describe('Job Manager', function () {
describe('Inline jobs', function () {
it('adds a job to a queue', async function () {
const spy = sinon.spy();
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
jobManager.addJob({
job: spy,
@ -48,7 +51,7 @@ describe('Job Manager', function () {
it('handles failed job gracefully', async function () {
const spy = sinon.stub().throws();
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
jobManager.addJob({
job: spy,
@ -69,7 +72,7 @@ describe('Job Manager', function () {
describe('Offloaded jobs', function () {
it('fails to schedule for invalid scheduling expression', function () {
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
try {
jobManager.addJob({
@ -82,7 +85,7 @@ describe('Job Manager', function () {
});
it('fails to schedule for no job name', function () {
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
try {
jobManager.addJob({
@ -95,7 +98,7 @@ describe('Job Manager', function () {
});
it('schedules a job using date format', async function () {
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
const timeInTenSeconds = new Date(Date.now() + 10);
const jobPath = path.resolve(__dirname, './jobs/simple.js');
@ -133,7 +136,7 @@ describe('Job Manager', function () {
});
it('schedules a job to run immediately', async function () {
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
const clock = FakeTimers.install({now: Date.now()});
const jobPath = path.resolve(__dirname, './jobs/simple.js');
@ -165,7 +168,7 @@ describe('Job Manager', function () {
});
it('fails to schedule a job with the same name to run immediately one after another', async function () {
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
const clock = FakeTimers.install({now: Date.now()});
const jobPath = path.resolve(__dirname, './jobs/simple.js');
@ -208,7 +211,7 @@ describe('Job Manager', function () {
throw new Error('job error');
};
const spyHandler = sinon.spy();
const jobManager = new JobManager({logging, errorHandler: spyHandler});
const jobManager = new JobManager({errorHandler: spyHandler});
jobManager.addJob({
job,
@ -228,7 +231,7 @@ describe('Job Manager', function () {
it('uses worker message handler when job sends a message', async function (){
const workerMessageHandlerSpy = sinon.spy();
const jobManager = new JobManager({logging, workerMessageHandler: workerMessageHandlerSpy});
const jobManager = new JobManager({workerMessageHandler: workerMessageHandlerSpy});
jobManager.addJob({
job: path.resolve(__dirname, './jobs/message.js'),
@ -250,7 +253,7 @@ describe('Job Manager', function () {
describe('Remove a job', function () {
it('removes a scheduled job from the queue', async function () {
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
const timeInTenSeconds = new Date(Date.now() + 10);
const jobPath = path.resolve(__dirname, './jobs/simple.js');
@ -270,7 +273,7 @@ describe('Job Manager', function () {
describe('Shutdown', function () {
it('gracefully shuts down an inline jobs', async function () {
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
jobManager.addJob({
job: require('./jobs/timed-job'),
@ -286,7 +289,7 @@ describe('Job Manager', function () {
});
it('gracefully shuts down an interval job', async function () {
const jobManager = new JobManager({logging});
const jobManager = new JobManager({});
jobManager.addJob({
at: 'every 5 seconds',