mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-25 02:31:59 -05:00
Added job status checks to job manager
refs ttps://github.com/TryGhost/Toolbox/issues/358 - One off jobs need a way to check for prior execution and await for their completion (in cases when it is reasonably short). - Added `hasExecuted` and `awaitCompletion` methods to the job manager allowing to monitor one off job state
This commit is contained in:
parent
b7853323ae
commit
6d5a5e90b1
2 changed files with 103 additions and 0 deletions
|
@ -1,4 +1,6 @@
|
|||
const path = require('path');
|
||||
const util = require('util');
|
||||
const setTimeoutPromise = util.promisify(setTimeout);
|
||||
const fastq = require('fastq');
|
||||
const later = require('@breejs/later');
|
||||
const Bree = require('bree');
|
||||
|
@ -229,6 +231,40 @@ class JobManager {
|
|||
this.addJob({name, job, data, offloaded});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the one-off job has ever been successfully executed
|
||||
* @param {String} name one-off job name
|
||||
*/
|
||||
async hasExecuted(name) {
|
||||
// TODO: return false if the job has failed?
|
||||
if (this._jobsRepository) {
|
||||
const persistedJob = await this._jobsRepository.read(name);
|
||||
return !!persistedJob;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} name one-off job name
|
||||
* @returns
|
||||
*/
|
||||
async awaitCompletion(name) {
|
||||
const persistedJob = await this._jobsRepository.read({
|
||||
name
|
||||
});
|
||||
|
||||
if (!persistedJob || !['finished', 'failed'].includes(persistedJob.get('status'))) {
|
||||
// NOTE: can implement exponential backoff here if that's ever needed
|
||||
await setTimeoutPromise(500);
|
||||
|
||||
return this.awaitCompletion(name);
|
||||
}
|
||||
|
||||
return !!persistedJob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an "offloaded" job from scheduled jobs queue.
|
||||
* It's NOT yet possible to remove "inline" jobs (will be possible when scheduling is added https://github.com/breejs/bree/issues/68).
|
||||
|
|
|
@ -502,6 +502,73 @@ describe('Job Manager', function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe('Job execution progress', function () {
|
||||
it('checks if job has ever been executed', async function () {
|
||||
const spy = sinon.spy();
|
||||
const JobModel = {
|
||||
findOne: sinon.stub()
|
||||
.withArgs('solovei')
|
||||
.onCall(0)
|
||||
.resolves(null)
|
||||
.onCall(1)
|
||||
.resolves(null)
|
||||
.resolves({id: 'unique', name: 'solovei'}),
|
||||
add: sinon.stub().resolves()
|
||||
};
|
||||
|
||||
const jobManager = new JobManager({JobModel});
|
||||
let executed = await jobManager.hasExecuted('solovei');
|
||||
should.equal(executed, false);
|
||||
|
||||
await jobManager.addOneOffJob({
|
||||
job: spy,
|
||||
name: 'solovei'
|
||||
});
|
||||
|
||||
assert.equal(JobModel.add.called, true);
|
||||
executed = await jobManager.hasExecuted('solovei');
|
||||
should.equal(executed, true);
|
||||
});
|
||||
|
||||
it('can wait for job completion', async function () {
|
||||
const spy = sinon.spy();
|
||||
let status = 'queued';
|
||||
const jobWithDelay = async () => {
|
||||
await delay(80);
|
||||
status = 'finished';
|
||||
spy();
|
||||
};
|
||||
const JobModel = {
|
||||
findOne: sinon.stub()
|
||||
// first call when adding a job
|
||||
.withArgs('solovei')
|
||||
.onCall(0)
|
||||
// first call when adding a job
|
||||
.resolves(null)
|
||||
.onCall(1)
|
||||
.resolves(null)
|
||||
|
||||
.resolves({
|
||||
id: 'unique',
|
||||
get: () => status
|
||||
}),
|
||||
add: sinon.stub().resolves()
|
||||
};
|
||||
|
||||
const jobManager = new JobManager({JobModel});
|
||||
|
||||
await jobManager.addOneOffJob({
|
||||
job: jobWithDelay,
|
||||
name: 'solovei',
|
||||
offloaded: false
|
||||
});
|
||||
|
||||
should.equal(spy.called, false);
|
||||
await jobManager.awaitCompletion('solovei');
|
||||
should.equal(spy.called, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Remove a job', function () {
|
||||
it('removes a scheduled job from the queue', async function () {
|
||||
const jobManager = new JobManager({});
|
||||
|
|
Loading…
Add table
Reference in a new issue