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'
13 paginationValidatorBuilder,
16 } from '../../middlewares'
17 import { listJobsValidator } from '../../middlewares/validators/jobs'
19 const jobsRouter = express.Router()
21 jobsRouter.use(apiRateLimiter)
23 jobsRouter.post('/pause',
25 ensureUserHasRight(UserRight.MANAGE_JOBS),
26 asyncMiddleware(pauseJobQueue)
29 jobsRouter.post('/resume',
31 ensureUserHasRight(UserRight.MANAGE_JOBS),
35 jobsRouter.get('/:state?',
36 openapiOperationDoc({ operationId: 'getJobs' }),
38 ensureUserHasRight(UserRight.MANAGE_JOBS),
39 paginationValidatorBuilder([ 'jobs' ]),
44 asyncMiddleware(listJobs)
47 // ---------------------------------------------------------------------------
53 // ---------------------------------------------------------------------------
55 async function pauseJobQueue (req: express.Request, res: express.Response) {
56 await JobQueue.Instance.pause()
58 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
61 function resumeJobQueue (req: express.Request, res: express.Response) {
62 JobQueue.Instance.resume()
64 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
67 async function listJobs (req: express.Request, res: express.Response) {
68 const state = req.params.state as JobState
69 const asc = req.query.sort === 'createdAt'
70 const jobType = req.query.jobType
72 const jobs = await JobQueue.Instance.listForApi({
74 start: req.query.start,
75 count: req.query.count,
79 const total = await JobQueue.Instance.count(state, jobType)
81 const result: ResultList<Job> = {
83 data: await Promise.all(jobs.map(j => formatJob(j, state)))
86 return res.json(result)
89 async function formatJob (job: BullJob, state?: JobState): Promise<Job> {
90 const error = isArray(job.stacktrace) && job.stacktrace.length !== 0
96 state: state || await job.getState(),
97 type: job.queueName as JobType,
100 ? { id: job.parent.id }
102 progress: job.progress as number,
103 priority: job.opts.priority,
105 createdAt: new Date(job.timestamp),
106 finishedOn: new Date(job.finishedOn),
107 processedOn: new Date(job.processedOn)