Need help with adonis-bull?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

Rocketseat
227 Stars 32 Forks MIT License 76 Commits 15 Opened issues

Description

The easiest way to start using an asynchronous job queue with AdonisJS. Ready for Adonis v5 ⚡️

Services available

!
?

Need anything else?

Contributors list


Adonis Bull

A Bull provider for AdonisJS Adonis Bull provides an easy way to start using Bull.

[![build-image]][build-url] [![coveralls-image]][coveralls-url] [![license-image]][license-url] [![npm-image]][npm-url]


This documentation refers to the stable version of Adonis Bull, for Adonis v4.x
> If you are using Adonis v5, click here.

Why

Using Bull with Adonis shouldn't be hard. It shouldn't require dozens of steps to configure it. That's why adonis-bull exists. It provides an easy way to use queues when developing applications with AdonisJS.

Install

adonis install @rocketseat/adonis-bull

Usage

Register the Bull commands at

start/app.js
const aceProviders = ['@rocketseat/adonis-bull/providers/Command']

Register the Bull provider at

start/app.js
const providers = [
  //...
  '@rocketseat/adonis-bull/providers/Bull',
]

Create a file with the

jobs
that will be processed at
start/jobs.js
:
module.exports = ['App/Jobs/UserRegisterEmail']

Add the config file at

config/bull.js
:
'use strict'

const Env = use('Env')

module.exports = { // redis connection connection: Env.get('BULL_CONNECTION', 'bull'), bull: { redis: { host: '127.0.0.1', port: 6379, password: null, db: 0, keyPrefix: '', }, }, remote: 'redis://redis.example.com?password=correcthorsebatterystaple', }

In the above file you can define redis connections, there you can pass all

Bull
queue configurations described here.

Create a file to initiate

Bull
at
preloads/bull.js
:
const Bull = use('Rocketseat/Bull')

Bull.process() // Optionally you can start BullBoard: .ui(9999, 'localhost') // http://localhost:9999 // You don't need to specify either port or hostname, the default port number is 9999 and the default hostname is localhost

Add .preLoad in server.js to initialize the bull preload

new Ignitor(require('@adonisjs/fold'))
  .appRoot(__dirname)
  .preLoad('preloads/bull') // Add This Line
  .fireHttpServer()
  .catch(console.error)

Creating your job

Create a class that mandatorily has the methods

key
and
handle
.

The

key
method is the unique identification of each job. It has to be a
static get
method.

The

handle
is the method that contains the functionality of your
job
.
const Mail = use('Mail')

class UserRegisterEmail { static get key() { return 'UserRegisterEmail-key' }

async handle(job) { const { data } = job // the 'data' variable has user data

await Mail.send('emails.welcome', data, (message) => {
  message
    .to(data.email)
    .from('<from-email>')
    .subject('Welcome to yardstick')
})

return data

} }

module.exports = UserRegisterEmail

You can use the

connection
static get method to specify which connection your
job
will work.
class UserRegisterEmail {
  // ...
  static get connection() {
    return 'remote'
  }
}

Events

The package has support for all events triggered in the bull, just add "on" and complete with the name of the event Ex:

onCompleted()
,
onActive()
,
onWaiting()
and etc.
class UserRegisterEmail {
  ...
  onCompleted(job, result) {}
  onActive(job) {}
  ...
}

module.exports = UserRegisterEmail;

Processing the jobs

Simple job

You can share the

job
of any
controller
,
hook
or any other place you might like:
const User = use('App/Models/User')
const Bull = use('Rocketseat/Bull')
const Job = use('App/Jobs/UserRegisterEmail')

class UserController { store ({ request, response }) { const data = request.only(['email', 'name', 'password'])

const user = await User.create(data)


Bull.add(Job.key, user)

} }

module.exports = UserController

Scheduled job

Sometimes it is necessary to schedule a job instead of shooting it imediately. You should use

schedule
for that:
const User = use('App/Models/User')
const Bull = use('Rocketseat/Bull')
const Job = use('App/Jobs/HolidayOnSaleEmail')

class HolidayOnSaleController { store ({ request, response }) { const data = request.only(['date', 'product_list']) // 2019-11-15 12:00:00

const products = await ProductOnSale.create(data)


Bull.schedule(Job.key, products, data.date)

} }

module.exports = HolidayOnSaleController

This

job
will be sent only on the specific date, wich for example here is on November 15th at noon.

When finishing a date, never use past dates because it will cause an error.

other ways of using

schedule
:
Bull.schedule(key, data, new Date('2019-11-15 12:00:00'))
Bull.schedule(key, data, '2 hours') // 2 hours from now
Bull.schedule(key, data, 60 * 1000) // 1 minute from now.

Advanced jobs

You can use the own

Bull
configs to improve your job:
Bull.add(key, data, {
  repeat: {
    cron: '0 30 12 * * WED,FRI',
  },
})

This

job
will be run at 12:30 PM, only on wednesdays and fridays.

Exceptions

To have a bigger control over errors that might occur on the line, the events that fail can be manipulated at the file

App/Exceptions/QueueHandler.js
:
const Sentry = use('Sentry')

class QueueHandler { async report(error, job) { Sentry.configureScope((scope) => { scope.setExtra(job) })

Sentry.captureException(error)

} }

module.exports = QueueHandler

Contributing

Thank you for being interested in making this package better. We encourage everyone to help improve this project with new features, bug fixes, or performance improvements. Please take a little bit of your time to read our guide to make this process faster and easier.

Contribution Guidelines

To understand how to submit an issue, commit and create pull requests, check our Contribution Guidelines.

Code of Conduct

We expect you to follow our Code of Conduct. You can read it to understand what kind of behavior will and will not be tolerated.

License

MIT License © Rocketseat

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.