ADR-0001. EventBus in-process + BullMQ cho eventing (không Kafka)
| Trường | Giá trị |
|---|---|
| Status | Accepted |
| Ngày | 2026-04-01 |
| Người quyết định | support-team |
| Thay thế | — |
Bối cảnh
- Helpdesk cần phản ứng với sự kiện domain (ticket created, status changed, assigned, message added) và chạy công việc nặng bất đồng bộ (assignment, giám sát SLA, escalation, thông báo, enrichment context, surveys).
- Chuẩn nền tảng cho eventing cross-service là Kafka.
@platformatic/kafkathậm chí được khai báo trongpackage.json. - Tuy nhiên, tất cả luồng event của helpdesk là trong-dịch-vụ: một event phát bởi một use-case được tiêu thụ bởi một listener trong cùng dịch vụ fan out tới job nền. Không dịch vụ nào khác đăng ký event helpdesk, và helpdesk không đăng ký topic bên ngoài nào.
Quyết định
Dùng một cơ chế trong-dịch-vụ hai tầng và không Kafka:
EventBusin-process (eventemitter3,EventBusComponent) — use-case phát eventTicketEventTypesquaTicketEmitter; listener trongsrc/application/events/listeners/xử lý chúng đồng bộ trong API process. Lỗi handler được bắt và log, không bao giờ crash emitter.- Hàng đợi BullMQ (
QueueComponent,WorkerComponent) — listener fan out tới hàng đợi nền Redis bền vững; một worker process riêng (RUN_MODE=worker) tiêu thụ chúng với retry/backoff theo từng hàng đợi.
@platformatic/kafka vẫn được khai báo nhưng không dùng (dependency chết).
Hệ quả
| Ưu | Nhược |
|---|---|
| Không phụ thuộc cụm Kafka cho một dịch vụ độc lập | Event không quan sát được từ bên ngoài — dịch vụ khác không thể đăng ký |
| Emit đồng bộ giữ response HTTP nhanh (công việc hoãn cho BullMQ) | EventBus là at-most-once; crash giữa emit và enqueue làm mất fan-out |
| BullMQ cho retry bền vững + DLQ mà không cần broker | Hai mô hình phân phối (in-process + queue) phải suy luận |
| Dev cục bộ đơn giản hơn (chỉ cần Redis) | Dep @platformatic/kafka chết gây hiểu lầm cho người đọc và phình install |
Phương án đã cân nhắc
| Tùy chọn | Vì sao bị từ chối |
|---|---|
| Kafka cho mọi eventing | Over-engineer cho luồng trong-dịch-vụ; thêm phụ thuộc broker không có subscriber bên ngoài |
| Chỉ BullMQ (không bus in-process) | Ép mọi phản ứng domain qua Redis ngay cả khi xử lý in-process đồng bộ là đủ |
| Outbox transactional + CDC | Nặng cho một dịch vụ không có consumer event bên ngoài |
Tham khảo
src/components/event-bus/event-bus.ts(eventemitter3)src/components/event-bus/event-registry.tssrc/application/events/emitters/ticket.emitter.tssrc/components/queue.component.tspackage.json(@platformatic/kafkađược khai báo, không dùng)