Skip to content

KABBOUCHI/adonisjs-jobs

Repository files navigation

AdonisJS Jobs

Job processing for AdonisJS v6 using BullMQ

Getting Started

This package is available in the npm registry.

pnpm install adonisjs-jobs

Next, configure the package by running the following command.

node ace configure adonisjs-jobs

Creating Jobs

You can create a new job by running the following command.

node ace jobs:make SendEmail

Listening for Jobs

First, you need to start the jobs listener, you can spawn multiple listeners to process jobs concurrently.

node ace jobs:listen  # default queue from env `REDIS_QUEUE`

node ace jobs:listen --queue=high
node ace jobs:listen --queue=high --queue=medium
node ace jobs:listen --queue=high,medium,low

node ace jobs:listen --queue=high --concurrency=3

Dispatching Jobs

Dispatching jobs is as simple as importing the job class and calling

import SendEmail from 'path/to/jobs/send_email.js'

await SendEmail.dispatch({ ... })

await SendEmail.dispatch({ ... }, { // for more job options check https://docs.bullmq.io/
  attempts: 3,
  delay: 1000,
})

Import Aliases (optional)

update your package.json and tsconfig.json to use import aliases

package.json

{
  "imports": {
    "#jobs/*": "./app/jobs/*.js"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "paths": {
      "#jobs/*": ["./app/jobs/*.js"]
    }
  }
}
import SendEmail from '#jobs/send_email.js'

await SendEmail.dispatch({ ... })

Jobs Dashboard

You can view the jobs dashboard by adding the following route to your start/routes.ts file.

import router from '@adonisjs/core/services/router'

router.jobs() // default is /jobs

// or

router.jobs('/my-jobs-dashboard')

router.jobs() returns a route group, you can add middleware to the group

router.jobs().use(
  middleware.auth({
    guards: ['basicAuth'],
  })
)

Tips

Job Completion on Kubernetes

In Kubernetes, prevent job termination by adjusting terminationGracePeriodSeconds (default is 30s) to allow jobs to finish gracefully.

spec:
  containers:
    - name: listen-jobs
      image: <IMAGE>
      command: ['node']
      args: ['ace', 'jobs:listen']
terminationGracePeriodSeconds: 1800

Experimental Features

Dispatch Closure

import { dispatch } from 'adonisjs-jobs/services/main'

await dispatch(async () => {
  const { default: User } = await import('#models/user')

  console.log(await User.query().count('*'))
})

await dispatch(async () => {
  const { default: mail } = await import('@adonisjs/mail/services/main')

  await mail.send((message) => {
    message
      .to('[email protected]')
      .from('[email protected]')
      .subject('Verify your email address')
      .htmlView('emails/verify_email')
  })
})