ADR-0003. Thực thi SLA qua cron monitor lặp lại + escalation worker
| Trường | Giá trị |
|---|---|
| Status | Accepted |
| Ngày | 2026-04-10 |
| Người quyết định | Phat Nguyen |
| Thay thế | - |
Bối cảnh
- Mỗi ticket có hai mốc hạn (phản hồi đầu tiên, xử lý xong) tính từ
SlaPolicycủa nó. Service phải phát hiện các mốc hạn sắp đến (cảnh báo), các trường hợp vi phạm, và vi phạm nghiêm trọng, rồi gửi thông báo và escalate. - Việc phát hiện mốc hạn về bản chất là theo thời gian: không có gì trong luồng request báo cho hệ thống biết "ticket này vừa vượt 75% mức SLA của nó." Các lựa chọn là dùng job trễ theo từng ticket được lên lịch ở mỗi ngưỡng, hoặc dùng một lượt quét định kỳ.
- Escalation (Level 1→2→3) phải đáng tin cậy và có thể retry, với mức ưu tiên cao hơn các tác vụ thường lệ.
Quyết định
Dùng một job cron BullMQ lặp lại kết hợp một escalation worker chuyên dụng:
QueueComponent.scheduleSlaMonitoring()đăng ký một job lặp lại trên queuehelpdesk.sla-monitorvớipattern: WORKER_CONFIG.SLA_MONITOR_INTERVAL(mỗi phút) và mộtjobId: 'sla-monitor-cron'cố định để các bản trùng không thể tích lũy. Khi khởi động, nó gỡ các bản lặp lại cũ trước.sla-monitor.worker(concurrency 1) chạyRunSlaMonitorUseCase, quét các hàngSlaTrackertheo từng lô (SLA_BATCH_SIZE = 100) để tìm trường hợp cảnh báo/vi phạm so vớiSLA_WARNING_THRESHOLDS(75/90/100/150).- Trường hợp vi phạm sẽ đưa job thông báo và job escalation vào queue
helpdesk.escalation(concurrency 5, priority 1, 3 lần retry với backoff theo hàm mũ), đượcescalation.worker→ProcessEscalationUseCasetiêu thụ. - Có thể kiểm tra thủ công qua
QueueComponent.triggerSlaCheck({ ticketId })ở mức priority HIGH.
Hệ quả
| Ưu | Nhược |
|---|---|
| Một lượt cron xử lý mọi ticket - không phát sinh việc lên lịch riêng cho từng ticket | Độ trễ phát hiện lên đến khoảng 1 phút (đúng bằng chu kỳ cron) |
Một jobId cố định duy nhất ngăn các bản lặp lại bị trùng qua các lần khởi động lại | Chi phí mỗi lượt quét tăng theo số ticket đang mở (đã giảm nhẹ bằng cách chia lô) |
| Escalation được tách riêng trên một queue ưu tiên cao, có retry | Monitor chạy concurrency 1 là giới hạn throughput cho các tenant rất lớn |
| Có sẵn đường trigger thủ công để kiểm tra lại theo mục tiêu cụ thể | Worker process phải đang chạy, nếu không việc thực thi SLA sẽ dừng âm thầm |
Lưu ý: việc phân công lại cho senior-agent từ Level 2 trở lên hiện đang bị tắt trong code (lời gọi
assignTicketUseCasebị comment) - escalation worker chỉ gửi thông báo. Xem Vận hành → Vấn đề đã biết.
Phương án đã cân nhắc
| Tùy chọn | Vì sao bị từ chối |
|---|---|
| Job trễ theo từng ticket ở mỗi ngưỡng | Bùng nổ số job được lên lịch; rối rắm khi phải lên lịch lại lúc đổi policy/priority |
| Cron bên ngoài / k8s CronJob gọi vào một endpoint | Thêm sự ràng buộc về hạ tầng; bản lặp lại BullMQ giữ việc lên lịch ngay trong ứng dụng và quan sát được |
| DB trigger / pg_cron | Đẩy logic nghiệp vụ vào database; khó kiểm thử và khó quan sát |
Tham khảo
src/components/queue.component.ts(scheduleSlaMonitoring,triggerSlaCheck)src/components/workers/sla-monitor.worker.ts,escalation.worker.tssrc/application/use-cases/sla-policy/run-sla-monitor.use-case.ts,process-escalation.use-case.tssrc/shared/common/constants/common.constant.ts(WORKER_CONFIG,SLA_WARNING_THRESHOLDS,ESCALATION_TIMING)