1 import { Job as BullJob } from 'bullmq'
2 import express from 'express'
3 import { HttpStatusCode, Job, JobState, JobType, ResultList, UserRight } from '@shared/models'
4 import { isArray } from '../../helpers/custom-validators/misc'
5 import { JobQueue } from '../../lib/job-queue'
12 paginationValidatorBuilder,
15 } from '../../middlewares'
16 import { listJobsValidator } from '../../middlewares/validators/jobs'
18 const jobsRouter = express.Router()
20 jobsRouter.post('/pause',
22 ensureUserHasRight(UserRight.MANAGE_JOBS),
23 asyncMiddleware(pauseJobQueue)
26 jobsRouter.post('/resume',
28 ensureUserHasRight(UserRight.MANAGE_JOBS),
32 jobsRouter.get('/:state?',
33 openapiOperationDoc({ operationId: 'getJobs' }),
35 ensureUserHasRight(UserRight.MANAGE_JOBS),
36 paginationValidatorBuilder([ 'jobs' ]),
41 asyncMiddleware(listJobs)
44 // ---------------------------------------------------------------------------
50 // ---------------------------------------------------------------------------
52 async function pauseJobQueue (req: express.Request, res: express.Response) {
53 await JobQueue.Instance.pause()
55 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
58 function resumeJobQueue (req: express.Request, res: express.Response) {
59 JobQueue.Instance.resume()
61 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
64 async function listJobs (req: express.Request, res: express.Response) {
65 const state = req.params.state as JobState
66 const asc = req.query.sort === 'createdAt'
67 const jobType = req.query.jobType
69 const jobs = await JobQueue.Instance.listForApi({
71 start: req.query.start,
72 count: req.query.count,
76 const total = await JobQueue.Instance.count(state, jobType)
78 const result: ResultList<Job> = {
80 data: await Promise.all(jobs.map(j => formatJob(j, state)))
83 return res.json(result)
86 async function formatJob (job: BullJob, state?: JobState): Promise<Job> {
87 const error = isArray(job.stacktrace) && job.stacktrace.length !== 0
93 state: state || await job.getState(),
94 type: job.queueName as JobType,
96 progress: job.progress as number,
97 priority: job.opts.priority,
99 createdAt: new Date(job.timestamp),
100 finishedOn: new Date(job.finishedOn),
101 processedOn: new Date(job.processedOn)