X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Flib%2Fjobs%2Fjob-scheduler.ts;h=2ae732b0f8368f6b292dfc8ef8aeebe78b947080;hb=ad0997adfb9e1e3b1ff54338d7558cf7b18440ea;hp=ad5f7f6d98bb0afcd137c472e1b1775427f6b8c0;hpb=e02643f32e4c97ca307f8fc5b69be79c40d70a3b;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/jobs/job-scheduler.ts b/server/lib/jobs/job-scheduler.ts index ad5f7f6d9..2ae732b0f 100644 --- a/server/lib/jobs/job-scheduler.ts +++ b/server/lib/jobs/job-scheduler.ts @@ -1,4 +1,5 @@ import { forever, queue } from 'async' +import * as Sequelize from 'sequelize' import { database as db } from '../../initializers/database' import { @@ -7,7 +8,10 @@ import { JOB_STATES } from '../../initializers' import { logger } from '../../helpers' -import { jobHandlers } from './handlers' +import { JobInstance } from '../../models' +import { JobHandler, jobHandlers } from './handlers' + +type JobQueueCallback = (err: Error) => void class JobScheduler { @@ -24,41 +28,39 @@ class JobScheduler { logger.info('Jobs scheduler activated.') - const jobsQueue = queue(this.processJob.bind(this)) + const jobsQueue = queue(this.processJob.bind(this)) // Finish processing jobs from a previous start const state = JOB_STATES.PROCESSING - db.Job.listWithLimit(limit, state, (err, jobs) => { - this.enqueueJobs(err, jobsQueue, jobs) - - forever( - next => { - if (jobsQueue.length() !== 0) { - // Finish processing the queue first - return setTimeout(next, JOBS_FETCHING_INTERVAL) - } - - const state = JOB_STATES.PENDING - db.Job.listWithLimit(limit, state, (err, jobs) => { - if (err) { - logger.error('Cannot list pending jobs.', { error: err }) - } else { - jobs.forEach(job => { - jobsQueue.push(job) - }) + db.Job.listWithLimit(limit, state) + .then(jobs => { + this.enqueueJobs(jobsQueue, jobs) + + forever( + next => { + if (jobsQueue.length() !== 0) { + // Finish processing the queue first + return setTimeout(next, JOBS_FETCHING_INTERVAL) } - // Optimization: we could use "drain" from queue object - return setTimeout(next, JOBS_FETCHING_INTERVAL) - }) - }, + const state = JOB_STATES.PENDING + db.Job.listWithLimit(limit, state) + .then(jobs => { + this.enqueueJobs(jobsQueue, jobs) - err => { logger.error('Error in job scheduler queue.', { error: err }) } - ) - }) + // Optimization: we could use "drain" from queue object + return setTimeout(next, JOBS_FETCHING_INTERVAL) + }) + .catch(err => logger.error('Cannot list pending jobs.', err)) + }, + + err => logger.error('Error in job scheduler queue.', err) + ) + }) + .catch(err => logger.error('Cannot list pending jobs.', err)) } - createJob (transaction, handlerName: string, handlerInputData: object, callback) { + createJob (transaction: Sequelize.Transaction, handlerName: string, handlerInputData: object) { const createQuery = { state: JOB_STATES.PENDING, handlerName, @@ -66,67 +68,62 @@ class JobScheduler { } const options = { transaction } - db.Job.create(createQuery, options).asCallback(callback) + return db.Job.create(createQuery, options) } - private enqueueJobs (err, jobsQueue, jobs) { - if (err) { - logger.error('Cannot list pending jobs.', { error: err }) - } else { - jobs.forEach(job => { - jobsQueue.push(job) - }) - } + private enqueueJobs (jobsQueue: AsyncQueue, jobs: JobInstance[]) { + jobs.forEach(job => jobsQueue.push(job)) } - private processJob (job, callback) { + private processJob (job: JobInstance, callback: (err: Error) => void) { const jobHandler = jobHandlers[job.handlerName] + if (jobHandler === undefined) { + logger.error('Unknown job handler for job %s.', job.handlerName) + return callback(null) + } logger.info('Processing job %d with handler %s.', job.id, job.handlerName) job.state = JOB_STATES.PROCESSING - job.save().asCallback(err => { - if (err) return this.cannotSaveJobError(err, callback) - - if (jobHandler === undefined) { - logger.error('Unknown job handler for job %s.', jobHandler.handlerName) - return callback() - } - - return jobHandler.process(job.handlerInputData, (err, result) => { - if (err) { - logger.error('Error in job handler %s.', job.handlerName, { error: err }) - return this.onJobError(jobHandler, job, result, callback) - } + return job.save() + .then(() => { + return jobHandler.process(job.handlerInputData) + }) + .then( + result => { + return this.onJobSuccess(jobHandler, job, result) + }, - return this.onJobSuccess(jobHandler, job, result, callback) + err => { + logger.error('Error in job handler %s.', job.handlerName, err) + return this.onJobError(jobHandler, job, err) + } + ) + .then(() => callback(null)) + .catch(err => { + this.cannotSaveJobError(err) + return callback(err) }) - }) } - private onJobError (jobHandler, job, jobResult, callback) { + private onJobError (jobHandler: JobHandler, job: JobInstance, err: Error) { job.state = JOB_STATES.ERROR - job.save().asCallback(err => { - if (err) return this.cannotSaveJobError(err, callback) - - return jobHandler.onError(err, job.id, jobResult, callback) - }) + return job.save() + .then(() => jobHandler.onError(err, job.id)) + .catch(err => this.cannotSaveJobError(err)) } - private onJobSuccess (jobHandler, job, jobResult, callback) { + private onJobSuccess (jobHandler: JobHandler, job: JobInstance, jobResult: any) { job.state = JOB_STATES.SUCCESS - job.save().asCallback(err => { - if (err) return this.cannotSaveJobError(err, callback) - - return jobHandler.onSuccess(err, job.id, jobResult, callback) - }) + return job.save() + .then(() => jobHandler.onSuccess(job.id, jobResult)) + .catch(err => this.cannotSaveJobError(err)) } - private cannotSaveJobError (err, callback) { - logger.error('Cannot save new job state.', { error: err }) - return callback(err) + private cannotSaveJobError (err: Error) { + logger.error('Cannot save new job state.', err) } }