# PoC-Study Message Queue in Node.js with BullMQ and Redis
## Doc:
[Official Website](https://bullmq.io/)
[Document](https://docs.bullmq.io/)
[Github](https://github.com/taskforcesh/bullmq)
[Medium](https://medium.com/@techsuneel99/message-queue-in-node-js-with-bullmq-and-redis-7fe5b8a21475)
## What is BullMQ?
>BullMQ is a Node.js library that implements a fast and robust queue system built on top of Redis that helps in resolving many modern-age micro-services architectures.
BullMQ: 用 Node.js 實作一個建構在 Redis 之上的 ~~message queue~~ job 系統

BullMQ 用到的 data types
## Basic Guide
### Workflow

### Producer
```javascript
import { Queue } from 'bullmq';
const myQueue = new Queue('foo', {
connection: {
host: "localhost",
port: 6379
}
});
async function addJobs() {
await myQueue.add('myJobName', { foo: 'bar' });
await myQueue.add('myJobName', { qux: 'baz' });
}
await addJobs();import { Queue } from 'bullmq';
const myQueue = new Queue('foo', {
connection: {
host: "localhost",
port: 6379
}
});
async function addJobs() {
await myQueue.add('myJobName', { foo: 'bar' });
await myQueue.add('myJobName', { qux: 'baz' });
}
await addJobs();
```
### Consumer
```javascript
import { Worker } from 'bullmq';
const worker = new Worker('foo', async job => {
console.log(job.data);
}, {
connection: {
host: "localhost",
port: 6379
}
});
```
## Demo
### Scenarios
> TODO
## Q & A
### Support to Python?
Bullmq 有支援 [python](https://docs.bullmq.io/python/introduction) 的 lib
> 目前還在 development 階段, 官方不建議用於 production 環境
或者是增加一個 interface:
> 參考上述的 Scenario: Interface

好處是只要透過 http 就可以發送 job, 但相對也增加了 endpoint 的維護成本
另外多了一層 interface, 也有相對應的 exception/error handling
### 從隊列崩潰後是否會有自動恢復的機制?
基本上 Bullmq 是將整套系統建立在 Redis 上, producer/consumer 各自獨立運作, 因此 application 端的系統錯誤不會影響到 message queue system, 而是和 Redis 的穩定度綁定
ioredis lib 支援 reconnections 機制, 可以自訂 Redis 連線異常時自動重新連接
> deatil about Redis connection options: [Source Code](https://github.com/redis/ioredis/blob/f68290e/lib/redis/RedisOptions.ts)
### 另一個重點: Stalled Job
Node.js 的 [event loop](https://nodejs.org/en/learn/asynchronous-work/event-loop-timers-and-nexttick) 機制, 讓 app 處理 DB or Http request 時可以避免 CPU 堵塞, 更有效率的排程
如果 job 執行的內容涉及到大量的 CPU 運算, event loop 機制失效, 這時就可能會發生 CPU 堵塞, 造成 queue 塞車, 產生 Stalled Job
Bullmq 預設最大的 [check duration](https://api.docs.bullmq.io/interfaces/v5.WorkerOptions.html#lockDuration) 是 30 秒, 如果執行時間超過 30 秒, job 將會被判斷為 failed 並且標記為 `job stalled more than allowable limit` ([default 1](https://api.docs.bullmq.io/interfaces/v5.WorkerOptions.html#maxStalledCount))
### 是否為 FIFO 的逐步消化?
預設就是 [FIFO](https://docs.bullmq.io/guide/jobs/fifo), 也支援 [LIFO](https://docs.bullmq.io/guide/jobs/lifo), [Repeatable](https://docs.bullmq.io/guide/jobs/repeatable), [Prioritized](https://docs.bullmq.io/guide/jobs/prioritized)
## Reference
其他相關的進階內容可以參考以下文件:
* [Persistent connections](https://docs.bullmq.io/bull/patterns/persistent-connections)
* [Failing fast when Redis is down](https://docs.bullmq.io/patterns/failing-fast-when-redis-is-down)
* [Retrying failing jobs](https://docs.bullmq.io/guide/retrying-failing-jobs)
* [Going to production](https://docs.bullmq.io/guide/going-to-production)
###### tags: `NodeJS`