Gestione delle Code
Libreria selezionata
La libreria che abbiamo scelto per la gestione delle code è la libreria BullMQ (opens in a new tab).

BullMQ BullMQ (Bull Message Queues) è una libreria che sfrutta Redis per la
gestione delle code e dei job. È utile non solo per la gestione delle code, ma anche per la gestione delle risorse e per scambiare informazione in maniera performante all'interno dei microservizi
Installazione
Per installare BullMQ è necessario eseguire il seguente comando: bash npm install bullmq
Creazione di una coda
Per creare una coda è necessario eseguire il seguente codice:
import { Queue } from 'bullmq' const queue = new Queue('queue-name') // dove queue-name è il nome della codaCreazione di un job
Per creare un job è necessario eseguire il seguente codice:
import { Queue } from 'bullmq'
const queue = new Queue('queue-name') // dove queue-name è il nome della coda
queue.add('job-name', { data: 'data' }) // dove job-name è il nome del job e data è il dato da passare al jobOgni job può contenere un dato che verrà passato al worker che dovrà eseguire il job. Il dato può essere di qualsiasi tipo, ma è consigliato usare un oggetto.
Creazione di un worker
Per creare un worker è necessario eseguire il seguente codice:
import { Queue, Worker } from 'bullmq'
const queue = new Queue('queue-name') // dove queue-name è il nome della coda
const worker = new Worker(
'queue-name', // dove queue-name è il nome della coda
async (job) => {
// dove job è il job da eseguire
...
}
)Il worker è una classe che permette di eseguire i job che vengono aggiunti alla coda. Il worker esegue il job in maniera asincrona e non blocca il thread principale.
Gestione delle connessioni
Sia il worker che la coda necessitano di una connessione a redis per poter funzionare e nel caso di BullMQ viene utilizzata la libreria redisio per la gestione delle connessioni.
I valori di default per la connessione sono: host: localhost e port: 6379
Per cambiare i valori di default è necessario eseguire il seguente codice:
import { Queue, Worker } from 'bullmq'
const connection = {
host: 'yourhost.domain.com', // dove yourhost.domain.com è l'host di redis
port: 9091 // dove 9091 è la porta di redis
}
const queue = new Queue('queue-name', { connection }) // dove queue-name è il nome della coda
const worker = new Worker(
'queue-name', // dove queue-name è il nome della coda
async (job) => {
// dove job è il job da eseguire
...
},
{ connection }
)Ogni istanza di coda e worker creerà una connessione diversa, nel caso sia invece necessario utilizzare una stessa connessione basterà passare come valore del campo connection un'istanza di redisio:
import { Queue, Worker } from 'bullmq'
import Redis from 'ioredis'
const connection = new Redis({
host: 'yourhost.domain.com', // dove yourhost.domain.com è l'host di redis
port: 9091 // dove 9091 è la porta di redis
})
const queue = new Queue('queue-name', { connection }) // dove queue-name è il nome della coda
const worker = new Worker(
'queue-name', // dove queue-name è il nome della coda
async (job) => {
// dove job è il job da eseguire
...
},
{ connection }
)In questo modo verrà utilizzata la stessa connessione per la coda e per il worker.
Concorrenza
I worker di BullMQ possono essere eseguiti in parallelo, per fare ciò è necessario passare come terzo parametro del worker (quindi nell'oggetto relativo alle opzioni del worker) il campo concurrency con il valore del numero di worker che si vogliono eseguire in parallelo:
import { Queue, Worker } from 'bullmq'
const queue = new Queue('queue-name') // dove queue-name è il nome della coda
const worker = new Worker(
'queue-name', // dove queue-name è il nome della coda
async (job) => {
// dove job è il job da eseguire
...
},
{ concurrency: 5 } // dove 5 è il numero di worker che si vogliono eseguire in parallelo
)In questo modo verranno eseguiti al massimo 5 worker in parallelo.
Il valore di default per il campo concurrency è 1, quindi se non viene
specificato verrà eseguito un solo worker alla volta.
Ricorda che la concorrenza è possibile solo nel momento in cui il worker stia eseguendo delle funzioni asincrone poiché questo è l'unico modo con cui Node gestisce la concorrenza.
Per poter eseguire più worker in parallelo in altri casi, essi dovreanno essere eseguiti in processi diversi (opens in a new tab).
Esecuzione del worker
Il worker, di default, viene eseguito non appena viene creato. Per evitare che il worker venga eseguito subito è necessario passare come quarto parametro dell'oggetto relativo alle opzioni del worker il campo autorun con il valore false:
import { Queue, Worker } from 'bullmq'
const queue = new Queue('queue-name') // dove queue-name è il nome della coda
const worker = new Worker(
'queue-name', // dove queue-name è il nome della coda
async (job) => {
// dove job è il job da eseguire
...
},
{ autorun: false } // dove false indica che il worker non deve essere eseguito subito
)
In questo modo il worker non verrà eseguito subito, ma sarà necessario eseguire il metodo worker.run() per farlo partire.
Il metodo worker.run() può essere eseguito in qualsiasi momento, anche dopo
che il worker è stato fermato.
Attenzione: il worker non verrà eseguito se non viene chiamato il metodo
worker.run() e verrà fermato solo se viene chiamato il metodo
worker.close()
Documentazione completa
Per una documentazione completa sui worker di BullMQ è possibile consultare il sito ufficiale qui (opens in a new tab).