adonis5-queue
Version:
Adonis JS 5 queue package based backed by Kue and Kue-scheduler
195 lines (151 loc) • 7.61 kB
Markdown
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
## Table of contents
- [adonis5-queue](#adonis5-queue)
- [Adonis5 Queue](#adonis5-queue)
- [Features](#features)
- [Consumer/Producer model](#consumerproducer-model)
- [Notices](#notices)
- [Installation](#installation)
- [Create a job](#create-a-job)
- [Run worker](#run-worker)
- [Job API](#job-api)
- [Queue API](#queue-api)
- [Access the queue](#access-the-queue)
- [Push job onto the queue](#push-job-onto-the-queue)
- [Remove jobs](#remove-jobs)
- [Run tests](#run-tests)
- [Development](#development)
- [Thanks](#thanks)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# adonis5-queue
> priority-queue worker-queue job-queue
[![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url]
# Adonis5 Queue
Adonis5 queue is a worker-based queue library for [AdonisJS](https://github.com/adonisjs/adonis-framework), it is backed by [Kue](https://github.com/Automattic/kue) and [Kue-Scheduler](https://github.com/lykmapipo/kue-scheduler).
## Features
- Ace commands for generating jobs and start workers
- Use your existing adonis modules in your queue processor
- (Close-to) Full kue/kue-scheduler API supported including future/repeat job scheduling
- Produce/Consumer model for structuring your job
- Simple and Elegant API for scheduling and processing your jobs
## Consumer/Producer model
Instead of defining Job as a single entity, this library separates the responsibility of job into consumer and producer, here are the definitions:
**Producer:** Define the static properties of the job, in kue's context, **supported** properties include **priority, attempts, backOff, delay, ttl and unique**. Documentations of each property can be found in Kue and Kue-scheduler's Github.
**Consumer:** Define the runtime properties of the job, in kue's context, **supported** properties include **concurrency** and the process handler.
Example of a basic producer/consumer pair can be found by generating a sample job using the ``node ace queue:job`` command.
## Notices
This version only support **Adonis V5+**.
## Installation
Install it:
```bash
npm i --save adonis5-queue
```
```
Connect all dependences:
```bash
node ace configure adonis5-queue
```
#### Create a job
Make your first job:
```bash
node ace queue:job ExampleJob
```
or:
```bash
node ace queue:job ExampleJob --jobId='custom-job-id'
```
The option `jobId` is optional, if not provided, the kue type for the job will be a kebab-case of the argument. i.e. SendEmail -> send-email.
This command will create job producers and consumers in designated directories, which are configurable in **config/queue.js** with **consumerPath** and **producerPath**; this defaults to **app/Jobs/{Consumers | Producers}**.
The job consumers and producers will both run in Adonis framework's context, thus you can easily use any supported libraries within the job file.
### Run worker
```sh
node ace queue:work
```
**Notice**: For multiworker usage, you can use tools such as [Supervisor](https://github.com/Supervisor/supervisor) or [PM2](https://github.com/Unitech/pm2) or sclalable docker containers with orchestrator such as [Docker Swarm](https://docs.docker.com/engine/swarm/) or [Kuberneties (k8s)](https://kubernetes.io/), and the command will be ``node ace queue:work`` in your app’s root directory.
## Job API
The producer job file supports Kue job properties which are defined as an ES6 ``get`` property in the class, see example by running `node ace queue:job`.
Refer to supported job properties above in the **Consumer/Producer Model** section.
The consumer job file supports Kue job's **concurrecy** defined as an ES6 `static get` property in the class, see example by running `node ace queue:job`.
The processing function is defined as an async function `async handle()` or `handle()` depending on whether your task is asynchronous. Within the task class, you can access constructor-injected payload with `this.data`.
The producer job class also supports job events, listed below:
```js
// with in producer class
// job has been created and scheduled
// useful for retrieving redis id for the job
onInit(Kue/Job job)
// See kue documentation for below
onEnqueue(String jobType)
onStart(String jobType)
onPromotion(String jobType)
onProgress(Float progress)
// data returned from handle() method
onComplete(Object data)
onRemove(String jobType)
// error caught in the handle() method
onFailed(Error error)
onFailedAttempts(Error error)
```
This producer job class itself is an Event Listener, thus you can export the data received from the job event to the outside world.
A useful scenario is to remove job after it has been initialized:
```js
// within job producer class
onInit(job) {
this.emit('init');
}
// outside of the consumer
// for queue.remove() see Queue API below
job.on('init', async () => await Queue.remove(job));
```
## Queue API
### Access the queue
```js
const Queue = use('@ioc:Adonis5/Queue');
```
### Push job onto the queue
```js
// optionally inject data into the job class using constructor
// and access it in the consumer handler using this.data
const ExampleJob = use('App/Jobs/Producer/ExampleJob');
Queue.dispatch(new ExampleJob({'data': 'whatever'}));
```
`Queue.dispatch()` has a second optional `String` argument default to 'now', which reflects the Kue-Scheduler API:
```js
// schedule a job immediately
Queue.dispatch(new ExampleJob, 'now');
// schedule a repeated job every 2 seconds
// basically embeding the 'every' method into the string itself
Queue.dispatch(new ExampleJob, 'every 2 seconds');
// schedule a single job in the future
Queue.dispatch(new ExampleJob, '2 seconds from now');
```
### Remove jobs
Remove a single job, the argument must be the **job instance** you created:
```js
// asynchronous removal...
Queue.remove(job).then(response => {}, error => {});
```
Clear all jobs:
```js
// also returns a promise
Queue.clear().then(response => {}, error => {});
```
Note: currently <i>clear()</i> will not trigger the <i>remove</i> event on the job.
### Run tests
Please clone [this repo](https://github.com/reg2005/adonis5-queue), install the dependencies, and run ``npm run build && npm run test`` to run the spec tests. (Make sure redis is installed and configured properly as required by Kue).
You can also contribute to the test repo by submitting issues and PRs.
## Development
Contributions are welcome! This is a community project so please send a pull request whenever you feel like to!
## Thanks
Many thanks to:
- [Harminder Virk](https://github.com/thetutlage)
- [Romain Lanz](https://github.com/RomainLanz)
- [Jackie Zhang](https://github.com/ReactiveXYZ-Dev) for older version (it used in Adonis 4) [Adonis queue pro](https://github.com/ReactiveXYZ-Dev/Adonis-Queue-Pro)
[travis-image]: https://img.shields.io/travis/reg2005/adonis5-queue/master.svg?style=for-the-badge&logo=travis
[travis-url]: https://travis-ci.org/reg2005/adonis5-queue "travis"
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
[typescript-url]: "typescript"
[npm-image]: https://img.shields.io/npm/v/adonis5-queue.svg?style=for-the-badge&logo=npm
[npm-url]: https://npmjs.org/package/adonis5-queue "npm"
[license-image]: https://img.shields.io/npm/l/adonis5-queue?color=blueviolet&style=for-the-badge
[license-url]: LICENSE.md "license"