runmq 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +173 -292
- package/dist/index.cjs +203 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +203 -12
- package/dist/index.js.map +1 -1
- package/package.json +40 -2
package/README.md
CHANGED
|
@@ -1,21 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img width="1479" height="612" alt="RunMQ-logo (4)" src="https://github.com/user-attachments/assets/50dc9187-26f9-4073-979b-31601c652e1f" />
|
|
3
|
+
<a href="https://badge.fury.io/js/runmq.svg">
|
|
4
|
+
<img src="https://badge.fury.io/js/runmq.svg"/>
|
|
5
|
+
</a>
|
|
6
|
+
<a href="https://github.com/semantic-release/semantic-release">
|
|
7
|
+
<img src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg"/>
|
|
8
|
+
</a>
|
|
9
|
+
</div>
|
|
2
10
|
|
|
3
|
-
RunMQ is a reliable message queue library for Node.js built on top of RabbitMQ. Supports async background processing and event-driven messaging for microservices, with automatic retries, schema validation, and DLQ.
|
|
4
11
|
|
|
5
|
-
RunMQ
|
|
6
|
-
|
|
7
|
-
-
|
|
12
|
+
<b>RunMQ</b> is a high-performance message queue library for <b>Node.js</b>, built on top of <b>RabbitMQ</b>’s rock-solid messaging guarantees.
|
|
13
|
+
|
|
14
|
+
It combines RabbitMQ’s proven reliability with a modern developer experience — offering simple APIs, built-in fault tolerance, and seamless scaling for distributed systems.
|
|
15
|
+
|
|
16
|
+
Whether you’re running <b>background jobs</b>, designing an <b>event-driven architecture</b>, or managing a <b>pub/sub event bus</b>, RunMQ provides everything you need — all in a <b>lightweight package</b> with a <b>simple DX</b>, <b>without the hassle of managing everything on your own</b>.
|
|
17
|
+
|
|
8
18
|
|
|
9
19
|
## Features
|
|
10
20
|
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **Isolated Queues**: Each processor
|
|
15
|
-
- **Schema Validation**: Optional
|
|
16
|
-
- **Concurrent
|
|
17
|
-
- **
|
|
18
|
-
- **Custom Logging**:
|
|
21
|
+
- **Reliable Message Processing with Retries**: Automatically retries failed messages with configurable delays and retry limits.
|
|
22
|
+
- **Dead Letter Queue (DLQ) Support**: Failed messages are seamlessly routed to a DLQ after all retry attempts are exhausted.
|
|
23
|
+
- **Pub/Sub with Atomic Delivery**: Publish a message once, and all subscribed consumers receive it atomically, without the need to publish multiple times.
|
|
24
|
+
- **Isolated Queues per Processor**: Each processor gets its own dedicated queue and DLQ, ensuring full isolation and predictable behavior across services.
|
|
25
|
+
- **Schema Validation**: Optional JSON Schema validation powered by AJV for safer message handling and data integrity.
|
|
26
|
+
- **Concurrent Consumers**: Scale either horizontally (multiple instances) or vertically (multiple consumers per queue, leveraging RabbitMQ prefetch) to maximize throughput and efficiency.
|
|
27
|
+
- **RabbitMQ Durability & Acknowledgements**: Leverages RabbitMQ’s persistent storage and acknowledgment model to guarantee at-least-once delivery, even across restarts and failures.
|
|
28
|
+
- **Custom Logging**: Plug in your own logger or use the default console logger for full control over message visibility.
|
|
19
29
|
|
|
20
30
|
## Installation
|
|
21
31
|
|
|
@@ -23,270 +33,129 @@ RunMQ can be used to implement multiple messaging or jobs processing patterns:
|
|
|
23
33
|
npm install runmq
|
|
24
34
|
```
|
|
25
35
|
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
RunMQ can be used to implement various messaging patterns. Here are two common architectures:
|
|
29
|
-
|
|
30
|
-
### 1. Event-Driven Architecture (Event Bus Pattern)
|
|
31
|
-
|
|
32
|
-
In this pattern, multiple processors (or services) subscribe to the same event topic. Each processor gets its own isolated queue and DLQ, enabling true microservices autonomy.
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
Publisher → Topic (user.created)
|
|
36
|
-
├→ Queue: emailService → DLQ: emailService_dlq
|
|
37
|
-
├→ Queue: analyticsService → DLQ: analyticsService_dlq
|
|
38
|
-
└→ Queue: notificationService → DLQ: notificationService_dlq
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
**Key Benefits:**
|
|
42
|
-
- Services remain independent and isolated
|
|
43
|
-
- Each service can fail/retry without affecting others
|
|
44
|
-
- Easy to add new services or processors by subscribing to existing topics
|
|
45
|
-
- Scalable with multiple concurrent workers
|
|
46
|
-
|
|
47
|
-
### 2. Background Processing Pattern
|
|
36
|
+
## Quick Start
|
|
48
37
|
|
|
49
|
-
|
|
38
|
+
### Initialize RunMQ
|
|
39
|
+
The first step is to connect to RabbitMQ
|
|
50
40
|
|
|
51
|
-
```
|
|
52
|
-
|
|
41
|
+
```typescript
|
|
42
|
+
const runMQ = await RunMQ.start({
|
|
43
|
+
url: 'amqp://localhost:5672',
|
|
44
|
+
reconnectDelay: 5000, // Optional, default: 5000ms
|
|
45
|
+
maxReconnectAttempts: 5, // Optional, default: 5
|
|
46
|
+
management: {
|
|
47
|
+
url: "http://localhost:15673/",
|
|
48
|
+
username: "guest",
|
|
49
|
+
password: "guest"
|
|
50
|
+
};
|
|
51
|
+
});
|
|
53
52
|
```
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
- Dead letter queue for failed jobs
|
|
54
|
+
#### Notes:
|
|
55
|
+
- `reconnectDelay` defines the wait time between reconnection attempts.
|
|
56
|
+
- `maxReconnectAttempts` limits the number of retries when RabbitMQ is unavailable.
|
|
57
|
+
- Management configuration is optional but **highly recommended** to enables dynamic TTL via RabbitMQ policies; otherwise, RunMQ uses queue-based TTL.
|
|
60
58
|
|
|
61
|
-
|
|
59
|
+
### Processing side
|
|
62
60
|
|
|
63
|
-
|
|
61
|
+
It’s important that processors run before publishing messages, because queues are created internally when a consumer starts for the first time.
|
|
64
62
|
|
|
65
63
|
```typescript
|
|
66
64
|
import { RunMQ } from 'runmq';
|
|
67
65
|
|
|
68
|
-
// 1
|
|
69
|
-
const runMQ = await RunMQ.start({
|
|
70
|
-
url: 'amqp://localhost:5672',
|
|
71
|
-
reconnectDelay: 5000, // optional, default: 5000ms
|
|
72
|
-
maxReconnectAttempts: 5 // optional, default: 5
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
// 2. Process messages (create a consumer)
|
|
66
|
+
// Processor 1: Email Service
|
|
76
67
|
await runMQ.process('user.created', {
|
|
77
|
-
name: 'emailService', // Unique processor name (creates isolated queue)
|
|
78
|
-
consumersCount: 2, //
|
|
79
|
-
attempts: 3, //
|
|
80
|
-
attemptsDelay: 2000
|
|
68
|
+
name: 'emailService', // Unique processor name (creates an isolated queue)
|
|
69
|
+
consumersCount: 2, // Process up to 2 messages concurrently
|
|
70
|
+
attempts: 3, // Retry failed messages up to 3 times
|
|
71
|
+
attemptsDelay: 2000 // Wait 2 seconds between retries
|
|
81
72
|
}, async (message) => {
|
|
82
|
-
|
|
83
|
-
console.log('Received:', message.message);
|
|
73
|
+
console.log('EmailService received:', message.message);
|
|
84
74
|
await sendEmail(message.message);
|
|
85
75
|
});
|
|
86
76
|
|
|
87
|
-
//
|
|
88
|
-
runMQ.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
77
|
+
// Processor 2: SMS Service
|
|
78
|
+
await runMQ.process('user.created', {
|
|
79
|
+
name: 'smsService', // Unique processor name (separate queue)
|
|
80
|
+
consumersCount: 1, // Process 1 message at a time
|
|
81
|
+
attempts: 5, // Retry failed messages up to 5 times
|
|
82
|
+
attemptsDelay: 1000, // Wait 1 second between retries,
|
|
83
|
+
usePoliciesForDelay: true // highly recommended, default is false
|
|
84
|
+
}, async (message) => {
|
|
85
|
+
console.log('SMSService received:', message.message);
|
|
86
|
+
await sendSMS(message.message);
|
|
92
87
|
});
|
|
93
|
-
|
|
94
|
-
// That's it! The message will be delivered to all processors subscribed to 'user.created'
|
|
95
88
|
```
|
|
96
89
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
90
|
+
#### Notes:
|
|
91
|
+
- `name` is the unique identifier for each processor.
|
|
92
|
+
- RunMQ supports <b>Pub/Sub</b> out-of-the-box: multiple processors can consume the same message independently.
|
|
93
|
+
- Example: When a user is created, one processor can send an email verification while another sends an SMS.
|
|
94
|
+
- Each processor can have its own configuration for:
|
|
95
|
+
- `attempts` How many the message will be retried
|
|
96
|
+
- `attemptsDelay` The delay between attempts, and if management config is provided, it can be changed anytime!
|
|
97
|
+
- `consumersCount` The concurrency level, how many messages can be processed in the same time.
|
|
98
|
+
- `usePoliciesForDelay` Enable this to let RunMQ use policies for defining delay queue TTL. Highly recommended, as it allows you to adjust delay times dynamically without re-declaring queues.
|
|
102
99
|
|
|
103
|
-
###
|
|
104
|
-
|
|
105
|
-
When a user registers, multiple services need to react independently.
|
|
100
|
+
### Publishing side
|
|
106
101
|
|
|
107
102
|
```typescript
|
|
108
|
-
import { RunMQ, RunMQMessage } from 'runmq';
|
|
109
|
-
|
|
110
|
-
interface UserCreatedEvent {
|
|
111
|
-
userId: string;
|
|
112
|
-
email: string;
|
|
113
|
-
name: string;
|
|
114
|
-
createdAt: string;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// Initialize RunMQ in each service
|
|
118
|
-
const runMQ = await RunMQ.start({
|
|
119
|
-
url: 'amqp://localhost:5672'
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// ============================================
|
|
123
|
-
// SERVICE 1: Email Service
|
|
124
|
-
// ============================================
|
|
125
|
-
await runMQ.process<UserCreatedEvent>('user.created', {
|
|
126
|
-
name: 'emailService', // Creates queue: emailService
|
|
127
|
-
consumersCount: 2,
|
|
128
|
-
attempts: 3,
|
|
129
|
-
attemptsDelay: 2000
|
|
130
|
-
}, async (message: RunMQMessage<UserCreatedEvent>) => {
|
|
131
|
-
console.log(`[Email Service] Sending welcome email to ${message.message.email}`);
|
|
132
|
-
await sendWelcomeEmail(message.message);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// ============================================
|
|
136
|
-
// SERVICE 2: Analytics Service
|
|
137
|
-
// ============================================
|
|
138
|
-
await runMQ.process<UserCreatedEvent>('user.created', {
|
|
139
|
-
name: 'analyticsService', // Creates queue: analyticsService
|
|
140
|
-
consumersCount: 1,
|
|
141
|
-
attempts: 3
|
|
142
|
-
}, async (message: RunMQMessage<UserCreatedEvent>) => {
|
|
143
|
-
console.log(`[Analytics] Recording user registration for ${message.message.userId}`);
|
|
144
|
-
await trackUserRegistration(message.message);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// ============================================
|
|
148
|
-
// SERVICE 3: Notification Service
|
|
149
|
-
// ============================================
|
|
150
|
-
await runMQ.process<UserCreatedEvent>('user.created', {
|
|
151
|
-
name: 'notificationService', // Creates queue: notificationService
|
|
152
|
-
consumersCount: 3,
|
|
153
|
-
attempts: 5,
|
|
154
|
-
attemptsDelay: 1000
|
|
155
|
-
}, async (message: RunMQMessage<UserCreatedEvent>) => {
|
|
156
|
-
console.log(`[Notifications] Sending push notification to ${message.message.userId}`);
|
|
157
|
-
await sendPushNotification(message.message);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
// ============================================
|
|
161
|
-
// PUBLISHER: User Registration Handler
|
|
162
|
-
// ============================================
|
|
163
|
-
// When a user registers, publish one event
|
|
164
103
|
runMQ.publish('user.created', {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
createdAt: new Date().toISOString()
|
|
104
|
+
userId: '123',
|
|
105
|
+
email: 'user@example.com',
|
|
106
|
+
name: 'John Doe'
|
|
169
107
|
});
|
|
170
|
-
|
|
171
|
-
// All three services receive the event independently!
|
|
172
108
|
```
|
|
173
109
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
Want to add a new service? Just subscribe to existing events:
|
|
110
|
+
✅ Each processor receives the message independently without needing multiple publishes.
|
|
177
111
|
|
|
178
|
-
|
|
179
|
-
// NEW SERVICE 4: CRM Sync Service
|
|
180
|
-
await runMQ.process<UserCreatedEvent>('user.created', {
|
|
181
|
-
name: 'crmSyncService', // Creates new isolated queue
|
|
182
|
-
consumersCount: 1,
|
|
183
|
-
attempts: 3
|
|
184
|
-
}, async (message: RunMQMessage<UserCreatedEvent>) => {
|
|
185
|
-
console.log(`[CRM] Syncing user to CRM: ${message.message.userId}`);
|
|
186
|
-
await syncToCRM(message.message);
|
|
187
|
-
});
|
|
112
|
+
<br>
|
|
188
113
|
|
|
189
|
-
|
|
190
|
-
// No changes needed to existing services!
|
|
191
|
-
```
|
|
114
|
+
## Patterns in details
|
|
192
115
|
|
|
193
|
-
|
|
116
|
+
RunMQ can be used to implement various messaging patterns. Two common architectures are:
|
|
194
117
|
|
|
195
|
-
###
|
|
118
|
+
### 1. Event-Driven Architecture (Event Bus Pattern)
|
|
196
119
|
|
|
197
|
-
The
|
|
198
|
-
Where there's a publisher queuing jobs, and a worker service processing them asynchronously with retries and DLQ support.
|
|
120
|
+
The Event Bus pattern allows multiple services (or processors) to react independently to the same events. Each service has its own queue and DLQ, ensuring full isolation and autonomy.
|
|
199
121
|
|
|
200
|
-
```
|
|
201
|
-
|
|
122
|
+
```
|
|
123
|
+
Publisher → Topic (user.created)
|
|
124
|
+
├→ Queue: emailService → DLQ: emailService_dlq
|
|
125
|
+
├→ Queue: analyticsService → DLQ: analyticsService_dlq
|
|
126
|
+
└→ Queue: notificationService → DLQ: notificationService_dlq
|
|
127
|
+
```
|
|
202
128
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
129
|
+
**Key insights:**
|
|
130
|
+
- Publishing a single message delivers it to all processors subscribed to the topic.
|
|
131
|
+
- Each processor can have its own retry policy, consumer count, and delay configuration.
|
|
132
|
+
- Easily add new services by subscribing to existing topics.
|
|
133
|
+
- Dead Letter Queues allow failed messages to be captured without affecting other services.
|
|
134
|
+
- This architecture ensures microservices autonomy, reliability, and scalability.
|
|
135
|
+
- Schema validation ensures that only valid messages are processed; invalid messages can be routed to the DLQ automatically.
|
|
209
136
|
|
|
210
|
-
|
|
211
|
-
url: 'amqp://localhost:5672'
|
|
212
|
-
});
|
|
137
|
+
### 2. Background Processing Pattern
|
|
213
138
|
|
|
214
|
-
|
|
215
|
-
// WORKER: Email Processing Service
|
|
216
|
-
// ============================================
|
|
217
|
-
await runMQ.process<EmailJob>('email.send', {
|
|
218
|
-
name: 'emailWorker', // Single queue for job processing
|
|
219
|
-
consumersCount: 5, // 5 concurrent workers
|
|
220
|
-
attempts: 3,
|
|
221
|
-
attemptsDelay: 5000,
|
|
222
|
-
messageSchema: {
|
|
223
|
-
type: 'ajv',
|
|
224
|
-
schema: {
|
|
225
|
-
type: 'object',
|
|
226
|
-
properties: {
|
|
227
|
-
to: { type: 'string', format: 'email' },
|
|
228
|
-
subject: { type: 'string' },
|
|
229
|
-
body: { type: 'string' },
|
|
230
|
-
attachments: {
|
|
231
|
-
type: 'array',
|
|
232
|
-
items: { type: 'string' }
|
|
233
|
-
}
|
|
234
|
-
},
|
|
235
|
-
required: ['to', 'subject', 'body']
|
|
236
|
-
},
|
|
237
|
-
failureStrategy: 'dlq'
|
|
238
|
-
}
|
|
239
|
-
}, async (message: RunMQMessage<EmailJob>) => {
|
|
240
|
-
console.log(`[Worker] Sending email to ${message.message.to}`);
|
|
241
|
-
|
|
242
|
-
await sendEmail({
|
|
243
|
-
to: message.message.to,
|
|
244
|
-
subject: message.message.subject,
|
|
245
|
-
body: message.message.body,
|
|
246
|
-
attachments: message.message.attachments
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
console.log(`[Worker] Email sent successfully to ${message.message.to}`);
|
|
250
|
-
});
|
|
139
|
+
RunMQ can also act as a job queue for background tasks. A worker service processes jobs from a dedicated queue with retries and DLQ support.
|
|
251
140
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
// ============================================
|
|
255
|
-
// Your API can now queue emails for background processing
|
|
256
|
-
app.post('/api/send-email', async (req, res) => {
|
|
257
|
-
const { to, subject, body } = req.body;
|
|
258
|
-
|
|
259
|
-
// Queue the job - returns immediately
|
|
260
|
-
runMQ.publish('email.send', {
|
|
261
|
-
to,
|
|
262
|
-
subject,
|
|
263
|
-
body,
|
|
264
|
-
attachments: []
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
res.json({ status: 'queued' });
|
|
268
|
-
});
|
|
141
|
+
```
|
|
142
|
+
Publisher → Topic (email.send) → Queue: emailWorker → DLQ: emailWorker_dlq
|
|
269
143
|
```
|
|
270
144
|
|
|
271
|
-
|
|
145
|
+
**Key insights:**
|
|
146
|
+
- Dead Letter Queues allow failed messages to be captured without affecting other services.
|
|
147
|
+
- Schema validation ensures that only valid messages are processed; invalid messages can be routed to the DLQ automatically.
|
|
148
|
+
- Multiple concurrent workers can process jobs in parallel for high throughput.
|
|
272
149
|
|
|
273
|
-
|
|
274
|
-
API Request → Publish Job → Queue (emailWorker)
|
|
275
|
-
↓
|
|
276
|
-
5 Concurrent Workers
|
|
277
|
-
↓
|
|
278
|
-
[Success] or [Try processing for 3 times]
|
|
279
|
-
↓
|
|
280
|
-
[Final Failure] → DLQ (emailWorker_dlq)
|
|
281
|
-
```
|
|
150
|
+
<br>
|
|
282
151
|
|
|
283
|
-
## Features
|
|
152
|
+
## Advanced Features
|
|
284
153
|
|
|
285
154
|
### Schema Validation
|
|
286
155
|
|
|
287
|
-
RunMQ supports JSON
|
|
288
|
-
Currently,
|
|
289
|
-
|
|
156
|
+
RunMQ supports JSON Schema validation to ensure message integrity, so only valid messages are passed to your processors.
|
|
157
|
+
- Currently, AJV is supported for schema validation.
|
|
158
|
+
- Invalid messages are sent directly to the DLQ without being sent to the processor.
|
|
290
159
|
|
|
291
160
|
```typescript
|
|
292
161
|
const orderSchema = {
|
|
@@ -326,96 +195,108 @@ await runMQ.process('order.placed', {
|
|
|
326
195
|
await processOrder(message.message);
|
|
327
196
|
});
|
|
328
197
|
```
|
|
198
|
+
**Key insights:**
|
|
199
|
+
- Schema validation enforces message correctness before processing, reducing runtime errors.
|
|
200
|
+
- Only messages matching the schema reach your business logic.
|
|
201
|
+
- DLQ ensures that invalid messages are captured and can be inspected later.
|
|
329
202
|
|
|
330
|
-
###
|
|
203
|
+
### Policies for delay between attempts
|
|
331
204
|
|
|
332
|
-
|
|
205
|
+
RunMQ can leverage RabbitMQ policies to manage the delay between attempts, it's not used by default, however it's <b>highly recommended</b> to enable it.
|
|
333
206
|
|
|
334
|
-
-
|
|
335
|
-
-
|
|
207
|
+
- When `usePoliciesForDelay` is enabled, RunMQ creates delay queues with TTL configured via RabbitMQ policies rather than hard-coding TTL in the queue itself.
|
|
208
|
+
- Hard-coding the TTL requires manual queue re-declaration to change delays, which can involve deleting queues - making it cumbersome and error-prone.
|
|
209
|
+
- Policies allow dynamic updates to the TTL without recreating queues — you can change attempts delay anytime, and RunMQ will take care of the rest.
|
|
336
210
|
|
|
337
|
-
|
|
338
|
-
-
|
|
339
|
-
-
|
|
340
|
-
-
|
|
341
|
-
- ✅ Easy to monitor and debug per-processor queues
|
|
342
|
-
|
|
343
|
-
Example:
|
|
344
|
-
```typescript
|
|
345
|
-
// Creates queue: userEmailService and userEmailService_dlq
|
|
346
|
-
await runMQ.process('user.created', { name: 'userEmailService', ... }, handler);
|
|
347
|
-
|
|
348
|
-
// Creates queue: userAnalytics and userAnalytics_dlq
|
|
349
|
-
await runMQ.process('user.created', { name: 'userAnalytics', ... }, handler);
|
|
350
|
-
```
|
|
211
|
+
#### Benefits
|
|
212
|
+
- Flexible and easy management of retry delays
|
|
213
|
+
- Reduces operational overhead
|
|
214
|
+
- Fully compatible with RunMQ’s retry and DLQ mechanisms
|
|
351
215
|
|
|
352
216
|
### Custom Logger
|
|
353
217
|
|
|
354
|
-
|
|
218
|
+
RunMQ uses a default console logger, but you can provide a custom logger by implementing the RunMQLogger interface:
|
|
355
219
|
|
|
356
220
|
```typescript
|
|
357
221
|
import { RunMQLogger } from 'runmq';
|
|
358
222
|
|
|
359
223
|
class CustomLogger implements RunMQLogger {
|
|
360
224
|
log(message: string): void {
|
|
361
|
-
//
|
|
225
|
+
// Custom info logging
|
|
362
226
|
}
|
|
363
227
|
|
|
364
228
|
error(message: string, error?: any): void {
|
|
365
|
-
//
|
|
229
|
+
// Custom error logging
|
|
366
230
|
}
|
|
367
231
|
}
|
|
368
232
|
|
|
233
|
+
// Pass the custom logger when starting RunMQ
|
|
369
234
|
const runMQ = await RunMQ.start(config, new CustomLogger());
|
|
370
235
|
```
|
|
371
236
|
|
|
372
|
-
|
|
237
|
+
**Key insights:**
|
|
238
|
+
- Custom loggers allow integration with centralized logging systems (e.g., Winston, Bunyan, Datadog).
|
|
239
|
+
- Both info and error methods can be customized to suit your monitoring strategy.
|
|
240
|
+
|
|
241
|
+
<br>
|
|
242
|
+
|
|
243
|
+
## ⚙️ Types
|
|
373
244
|
|
|
374
245
|
### Connection Configuration
|
|
375
246
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
247
|
+
| Property | Type | Default | Description |
|
|
248
|
+
|----------|------|---------|-------------|
|
|
249
|
+
| `url` | `string` | — | The URL of the RabbitMQ server. |
|
|
250
|
+
| `reconnectDelay` | `number` | `5000` | Delay in milliseconds before attempting to reconnect after a disconnection. |
|
|
251
|
+
| `maxReconnectAttempts` | `number` | `5` | Maximum number of reconnection attempts. |
|
|
252
|
+
| `management` | `ManagementConfiguration` | — | RabbitMQ management API configuration. |
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
### Management configuration
|
|
257
|
+
|
|
258
|
+
| Property | Type | Default | Description |
|
|
259
|
+
|----------|------|---------|-------------|
|
|
260
|
+
| `url` | `string` | `"http://localhost:15672/"` | The URL of the RabbitMQ management API. |
|
|
261
|
+
| `username` | `string` | `"guest"` | Username for management API authentication. |
|
|
262
|
+
| `password` | `string` | `"guest"` | Password for management API authentication. |
|
|
263
|
+
|
|
264
|
+
---
|
|
383
265
|
|
|
384
266
|
### Processor Configuration
|
|
385
267
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
268
|
+
| Property | Type | Default | Description |
|
|
269
|
+
|----------|------|---------|-------------|
|
|
270
|
+
| `name` | `string` | — | Unique name of the processor, used to create isolated queues. |
|
|
271
|
+
| `consumersCount` | `number` | — | Number of concurrent consumers for this processor. |
|
|
272
|
+
| `attempts` | `number` | `1` | Maximum attempts to process a message. |
|
|
273
|
+
| `attemptsDelay` | `number` | `1000` | Delay in milliseconds between attempts. |
|
|
274
|
+
| `messageSchema` | `MessageSchema` | — | Optional schema configuration for message validation. |
|
|
275
|
+
| `usePoliciesForDelay` | `boolean` | false | Optional configuration to use Policies for attempts delay, highly recommended. |
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
---
|
|
395
279
|
|
|
396
280
|
### Message Schema Configuration
|
|
397
281
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
404
|
-
```
|
|
282
|
+
| Property | Type | Description |
|
|
283
|
+
|----------|------|-------------|
|
|
284
|
+
| `type` | `'ajv'` | Type of schema used for validation (currently only AJV supported). |
|
|
285
|
+
| `schema` | `any` | Schema definition for validating messages. |
|
|
286
|
+
| `failureStrategy` | `'dlq'` | Strategy applied when schema validation fails (e.g., move to DLQ). |
|
|
405
287
|
|
|
406
|
-
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 📦 Message Structure
|
|
291
|
+
|
|
292
|
+
| Property | Type | Description |
|
|
293
|
+
|----------|------|-------------|
|
|
294
|
+
| `message` | `T` | Your message payload. |
|
|
295
|
+
| `meta.id` | `string` | Unique identifier of the message. |
|
|
296
|
+
| `meta.publishedAt` | `number` | Timestamp when the message was published. |
|
|
297
|
+
| `meta.correlationId` | `string` | Correlation identifier for tracing. |
|
|
407
298
|
|
|
408
|
-
```typescript
|
|
409
|
-
interface RunMQMessageContent<T> {
|
|
410
|
-
message: T; // Your message payload
|
|
411
|
-
meta: {
|
|
412
|
-
id: string; // The unique identifier of the message.
|
|
413
|
-
publishedAt: number; // The timestamp when the message was published.
|
|
414
|
-
correlationId: string; // The correlation identifier.
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
```
|
|
418
299
|
|
|
419
300
|
## License
|
|
420
301
|
|
|
421
|
-
MIT
|
|
302
|
+
MIT
|