@usermetrics/queuebit 1.0.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/LICENSE +21 -0
- package/README.md +276 -0
- package/docs/API.md +577 -0
- package/docs/EXAMPLES.md +330 -0
- package/docs/QUICKSTART.md +122 -0
- package/examples/browser-example.html +573 -0
- package/package.json +52 -0
- package/src/client-browser.js +134 -0
- package/src/client-node.js +112 -0
- package/src/client.js +73 -0
- package/src/index.js +7 -0
- package/src/server-runner.js +30 -0
- package/src/server.js +292 -0
package/docs/API.md
ADDED
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
# QueueBit API Documentation
|
|
2
|
+
|
|
3
|
+
QueueBit is a high-performance, socket-based message queue system with guaranteed delivery.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Server API](#server-api)
|
|
8
|
+
- [Client API](#client-api)
|
|
9
|
+
- [Message Format](#message-format)
|
|
10
|
+
- [Examples](#examples)
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Server API
|
|
15
|
+
|
|
16
|
+
### QueueBitServer
|
|
17
|
+
|
|
18
|
+
The server class that handles message queuing and delivery.
|
|
19
|
+
|
|
20
|
+
#### Constructor
|
|
21
|
+
|
|
22
|
+
Creates a new QueueBit server instance.
|
|
23
|
+
|
|
24
|
+
```javascript
|
|
25
|
+
const { QueueBitServer } = require('queuebit');
|
|
26
|
+
|
|
27
|
+
const server = new QueueBitServer(options);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Options:**
|
|
31
|
+
|
|
32
|
+
| Parameter | Type | Default | Description |
|
|
33
|
+
|-----------|------|---------|-------------|
|
|
34
|
+
| `port` | number | 3000 | Port number for the server |
|
|
35
|
+
| `maxQueueSize` | number | 10000 | Maximum messages per subject |
|
|
36
|
+
|
|
37
|
+
**Example:**
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
const server = new QueueBitServer({
|
|
41
|
+
port: 3000,
|
|
42
|
+
maxQueueSize: 50000
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### close()
|
|
47
|
+
|
|
48
|
+
Shuts down the server and closes all connections.
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
server.close();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Example:**
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
// Graceful shutdown
|
|
58
|
+
process.on('SIGINT', () => {
|
|
59
|
+
console.log('Shutting down...');
|
|
60
|
+
server.close();
|
|
61
|
+
process.exit(0);
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Client API
|
|
68
|
+
|
|
69
|
+
### QueueBitClient
|
|
70
|
+
|
|
71
|
+
The client class for connecting to a QueueBit server.
|
|
72
|
+
|
|
73
|
+
#### Constructor
|
|
74
|
+
|
|
75
|
+
Creates a new client connection to the server.
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
const { QueueBitClient } = require('queuebit');
|
|
79
|
+
|
|
80
|
+
const client = new QueueBitClient(url);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Parameters:**
|
|
84
|
+
|
|
85
|
+
| Parameter | Type | Default | Description |
|
|
86
|
+
|-----------|------|---------|-------------|
|
|
87
|
+
| `url` | string | 'http://localhost:3000' | Server URL |
|
|
88
|
+
|
|
89
|
+
**Example:**
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
// Node.js
|
|
93
|
+
const { QueueBitClient } = require('queuebit');
|
|
94
|
+
const client = new QueueBitClient('http://localhost:3000');
|
|
95
|
+
|
|
96
|
+
// Browser
|
|
97
|
+
const client = new QueueBitClient('http://localhost:3000');
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
### publish(message, options)
|
|
103
|
+
|
|
104
|
+
Publishes a message to the queue.
|
|
105
|
+
|
|
106
|
+
**Parameters:**
|
|
107
|
+
|
|
108
|
+
| Parameter | Type | Required | Description |
|
|
109
|
+
|-----------|------|----------|-------------|
|
|
110
|
+
| `message` | object | Yes | The message data (must be a JSON object) |
|
|
111
|
+
| `options` | object | No | Publishing options |
|
|
112
|
+
|
|
113
|
+
**Options:**
|
|
114
|
+
|
|
115
|
+
| Option | Type | Description |
|
|
116
|
+
|--------|------|-------------|
|
|
117
|
+
| `subject` | string | Subject/topic for routing (default: 'default') |
|
|
118
|
+
| `expiry` | Date | Expiration date for the message |
|
|
119
|
+
| `removeAfterRead` | boolean | Remove message after first delivery (default: false) |
|
|
120
|
+
|
|
121
|
+
**Returns:** Promise<{ success: boolean, messageId?: string, error?: string }>
|
|
122
|
+
|
|
123
|
+
**Examples:**
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
// Basic publish
|
|
127
|
+
const result = await client.publish({
|
|
128
|
+
text: 'Hello, World!'
|
|
129
|
+
});
|
|
130
|
+
console.log(result); // { success: true, messageId: 'uuid-here' }
|
|
131
|
+
|
|
132
|
+
// Publish to specific subject
|
|
133
|
+
await client.publish(
|
|
134
|
+
{ orderId: 12345, status: 'pending' },
|
|
135
|
+
{ subject: 'orders' }
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Ephemeral message (removed after first read)
|
|
139
|
+
await client.publish(
|
|
140
|
+
{ notification: 'System update' },
|
|
141
|
+
{ removeAfterRead: true }
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
// Message with expiry (expires in 1 hour)
|
|
145
|
+
const expiryDate = new Date(Date.now() + 3600000);
|
|
146
|
+
await client.publish(
|
|
147
|
+
{ tempData: 'expires soon' },
|
|
148
|
+
{
|
|
149
|
+
subject: 'temp',
|
|
150
|
+
expiry: expiryDate
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
### subscribe(callback, options)
|
|
158
|
+
|
|
159
|
+
Subscribes to messages from the queue.
|
|
160
|
+
|
|
161
|
+
**Parameters:**
|
|
162
|
+
|
|
163
|
+
| Parameter | Type | Required | Description |
|
|
164
|
+
|-----------|------|----------|-------------|
|
|
165
|
+
| `callback` | function | Yes | Function called when message is received |
|
|
166
|
+
| `options` | object | No | Subscription options |
|
|
167
|
+
|
|
168
|
+
**Options:**
|
|
169
|
+
|
|
170
|
+
| Option | Type | Description |
|
|
171
|
+
|--------|------|-------------|
|
|
172
|
+
| `subject` | string | Subscribe to specific subject (default: 'default') |
|
|
173
|
+
| `queue` | string | Join a queue group for load-balanced delivery |
|
|
174
|
+
|
|
175
|
+
**Callback Signature:**
|
|
176
|
+
|
|
177
|
+
```javascript
|
|
178
|
+
(message: QueueMessage) => void
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Returns:** Promise<{ success: boolean, subject?: string, queue?: string }>
|
|
182
|
+
|
|
183
|
+
**Examples:**
|
|
184
|
+
|
|
185
|
+
```javascript
|
|
186
|
+
// Basic subscription
|
|
187
|
+
await client.subscribe((message) => {
|
|
188
|
+
console.log('Received:', message.data);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Subscribe to specific subject
|
|
192
|
+
await client.subscribe(
|
|
193
|
+
(message) => {
|
|
194
|
+
console.log('Order received:', message.data);
|
|
195
|
+
},
|
|
196
|
+
{ subject: 'orders' }
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
// Queue group (load-balanced across multiple subscribers)
|
|
200
|
+
await client.subscribe(
|
|
201
|
+
(message) => {
|
|
202
|
+
console.log('Processing task:', message.data);
|
|
203
|
+
// Only one subscriber in the group receives this message
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
subject: 'tasks',
|
|
207
|
+
queue: 'workers'
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
// Multiple subjects
|
|
212
|
+
await client.subscribe(
|
|
213
|
+
(message) => console.log('High priority:', message.data),
|
|
214
|
+
{ subject: 'priority.high' }
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
await client.subscribe(
|
|
218
|
+
(message) => console.log('Low priority:', message.data),
|
|
219
|
+
{ subject: 'priority.low' }
|
|
220
|
+
);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
### unsubscribe(options)
|
|
226
|
+
|
|
227
|
+
Unsubscribes from messages.
|
|
228
|
+
|
|
229
|
+
**Parameters:**
|
|
230
|
+
|
|
231
|
+
| Parameter | Type | Required | Description |
|
|
232
|
+
|-----------|------|----------|-------------|
|
|
233
|
+
| `options` | object | No | Unsubscription options |
|
|
234
|
+
|
|
235
|
+
**Options:**
|
|
236
|
+
|
|
237
|
+
| Option | Type | Description |
|
|
238
|
+
|--------|------|-------------|
|
|
239
|
+
| `subject` | string | Subject to unsubscribe from (default: 'default') |
|
|
240
|
+
| `queue` | string | Queue group to leave |
|
|
241
|
+
|
|
242
|
+
**Returns:** Promise<{ success: boolean }>
|
|
243
|
+
|
|
244
|
+
**Examples:**
|
|
245
|
+
|
|
246
|
+
```javascript
|
|
247
|
+
// Unsubscribe from default subject
|
|
248
|
+
await client.unsubscribe();
|
|
249
|
+
|
|
250
|
+
// Unsubscribe from specific subject
|
|
251
|
+
await client.unsubscribe({ subject: 'orders' });
|
|
252
|
+
|
|
253
|
+
// Leave queue group
|
|
254
|
+
await client.unsubscribe({
|
|
255
|
+
subject: 'tasks',
|
|
256
|
+
queue: 'workers'
|
|
257
|
+
});
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### getMessages(options)
|
|
263
|
+
|
|
264
|
+
Retrieves all messages currently in the queue for a subject.
|
|
265
|
+
|
|
266
|
+
**Parameters:**
|
|
267
|
+
|
|
268
|
+
| Parameter | Type | Required | Description |
|
|
269
|
+
|-----------|------|----------|-------------|
|
|
270
|
+
| `options` | object | No | Query options |
|
|
271
|
+
|
|
272
|
+
**Options:**
|
|
273
|
+
|
|
274
|
+
| Option | Type | Description |
|
|
275
|
+
|--------|------|-------------|
|
|
276
|
+
| `subject` | string | Subject to query (default: 'default') |
|
|
277
|
+
|
|
278
|
+
**Returns:** Promise<{ success: boolean, messages: QueueMessage[], count: number }>
|
|
279
|
+
|
|
280
|
+
**Examples:**
|
|
281
|
+
|
|
282
|
+
```javascript
|
|
283
|
+
// Get all messages from default subject
|
|
284
|
+
const result = await client.getMessages();
|
|
285
|
+
console.log(`Found ${result.count} messages`);
|
|
286
|
+
result.messages.forEach(msg => {
|
|
287
|
+
console.log(msg.data);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
// Get messages from specific subject
|
|
291
|
+
const orders = await client.getMessages({ subject: 'orders' });
|
|
292
|
+
console.log(`${orders.count} pending orders`);
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
### disconnect()
|
|
298
|
+
|
|
299
|
+
Disconnects from the server.
|
|
300
|
+
|
|
301
|
+
```javascript
|
|
302
|
+
client.disconnect();
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Example:**
|
|
306
|
+
|
|
307
|
+
```javascript
|
|
308
|
+
// Clean disconnect
|
|
309
|
+
await client.unsubscribe();
|
|
310
|
+
client.disconnect();
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Message Format
|
|
316
|
+
|
|
317
|
+
### QueueMessage
|
|
318
|
+
|
|
319
|
+
Every message in QueueBit has the following structure:
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
{
|
|
323
|
+
id: string, // Unique message identifier (UUID)
|
|
324
|
+
data: object, // Your message payload
|
|
325
|
+
subject: string, // Message subject/topic
|
|
326
|
+
timestamp: Date, // When message was published
|
|
327
|
+
expiry?: Date, // Optional expiration date
|
|
328
|
+
removeAfterRead: boolean // Whether to remove after first read
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
**Example:**
|
|
333
|
+
|
|
334
|
+
```javascript
|
|
335
|
+
{
|
|
336
|
+
id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
|
|
337
|
+
data: { orderId: 12345, amount: 99.99 },
|
|
338
|
+
subject: 'orders',
|
|
339
|
+
timestamp: '2024-01-15T10:30:00.000Z',
|
|
340
|
+
expiry: null,
|
|
341
|
+
removeAfterRead: false
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Examples
|
|
348
|
+
|
|
349
|
+
### Basic Pub/Sub
|
|
350
|
+
|
|
351
|
+
```javascript
|
|
352
|
+
const { QueueBitServer, QueueBitClient } = require('queuebit');
|
|
353
|
+
|
|
354
|
+
// Start server
|
|
355
|
+
const server = new QueueBitServer({ port: 3000 });
|
|
356
|
+
|
|
357
|
+
// Create clients
|
|
358
|
+
const publisher = new QueueBitClient('http://localhost:3000');
|
|
359
|
+
const subscriber = new QueueBitClient('http://localhost:3000');
|
|
360
|
+
|
|
361
|
+
// Subscribe
|
|
362
|
+
await subscriber.subscribe((message) => {
|
|
363
|
+
console.log('Received:', message.data);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
// Publish
|
|
367
|
+
await publisher.publish({ text: 'Hello, World!' });
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Request-Response Pattern
|
|
371
|
+
|
|
372
|
+
```javascript
|
|
373
|
+
// Responder
|
|
374
|
+
await responder.subscribe(async (message) => {
|
|
375
|
+
const { requestId, question } = message.data;
|
|
376
|
+
|
|
377
|
+
// Process request
|
|
378
|
+
const answer = processQuestion(question);
|
|
379
|
+
|
|
380
|
+
// Send response
|
|
381
|
+
await responder.publish(
|
|
382
|
+
{ requestId, answer },
|
|
383
|
+
{ subject: 'responses' }
|
|
384
|
+
);
|
|
385
|
+
}, { subject: 'requests' });
|
|
386
|
+
|
|
387
|
+
// Requester
|
|
388
|
+
const requestId = generateId();
|
|
389
|
+
|
|
390
|
+
// Listen for response
|
|
391
|
+
await requester.subscribe((message) => {
|
|
392
|
+
if (message.data.requestId === requestId) {
|
|
393
|
+
console.log('Answer:', message.data.answer);
|
|
394
|
+
}
|
|
395
|
+
}, { subject: 'responses' });
|
|
396
|
+
|
|
397
|
+
// Send request
|
|
398
|
+
await requester.publish(
|
|
399
|
+
{ requestId, question: 'What is 2+2?' },
|
|
400
|
+
{ subject: 'requests' }
|
|
401
|
+
);
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Work Queue Pattern
|
|
405
|
+
|
|
406
|
+
```javascript
|
|
407
|
+
// Producer
|
|
408
|
+
for (let i = 0; i < 100; i++) {
|
|
409
|
+
await producer.publish(
|
|
410
|
+
{ taskId: i, work: `Task ${i}` },
|
|
411
|
+
{ subject: 'tasks' }
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Worker 1
|
|
416
|
+
await worker1.subscribe((message) => {
|
|
417
|
+
console.log('Worker 1 processing:', message.data.taskId);
|
|
418
|
+
}, { subject: 'tasks', queue: 'workers' });
|
|
419
|
+
|
|
420
|
+
// Worker 2
|
|
421
|
+
await worker2.subscribe((message) => {
|
|
422
|
+
console.log('Worker 2 processing:', message.data.taskId);
|
|
423
|
+
}, { subject: 'tasks', queue: 'workers' });
|
|
424
|
+
|
|
425
|
+
// Tasks are distributed between Worker 1 and Worker 2
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
### Expiring Messages
|
|
429
|
+
|
|
430
|
+
```javascript
|
|
431
|
+
// Publish message that expires in 5 minutes
|
|
432
|
+
const expiryDate = new Date(Date.now() + 300000);
|
|
433
|
+
|
|
434
|
+
await client.publish(
|
|
435
|
+
{
|
|
436
|
+
code: 'ABC123',
|
|
437
|
+
description: 'Temporary access code'
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
subject: 'temp-codes',
|
|
441
|
+
expiry: expiryDate
|
|
442
|
+
}
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
// Message is automatically removed after expiry
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### One-Time Notifications
|
|
449
|
+
|
|
450
|
+
```javascript
|
|
451
|
+
// Publisher sends ephemeral notification
|
|
452
|
+
await publisher.publish(
|
|
453
|
+
{ alert: 'Server restarting in 5 minutes' },
|
|
454
|
+
{
|
|
455
|
+
subject: 'alerts',
|
|
456
|
+
removeAfterRead: true
|
|
457
|
+
}
|
|
458
|
+
);
|
|
459
|
+
|
|
460
|
+
// First subscriber gets the message
|
|
461
|
+
await subscriber1.subscribe((message) => {
|
|
462
|
+
console.log('Alert:', message.data.alert); // Receives message
|
|
463
|
+
}, { subject: 'alerts' });
|
|
464
|
+
|
|
465
|
+
// Second subscriber connects later
|
|
466
|
+
await subscriber2.subscribe((message) => {
|
|
467
|
+
console.log('Alert:', message.data.alert); // Won't receive it
|
|
468
|
+
}, { subject: 'alerts' });
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Multi-Topic Subscription
|
|
472
|
+
|
|
473
|
+
```javascript
|
|
474
|
+
const client = new QueueBitClient('http://localhost:3000');
|
|
475
|
+
|
|
476
|
+
// Subscribe to multiple topics
|
|
477
|
+
await client.subscribe((msg) => {
|
|
478
|
+
console.log('User event:', msg.data);
|
|
479
|
+
}, { subject: 'users' });
|
|
480
|
+
|
|
481
|
+
await client.subscribe((msg) => {
|
|
482
|
+
console.log('Order event:', msg.data);
|
|
483
|
+
}, { subject: 'orders' });
|
|
484
|
+
|
|
485
|
+
await client.subscribe((msg) => {
|
|
486
|
+
console.log('Payment event:', msg.data);
|
|
487
|
+
}, { subject: 'payments' });
|
|
488
|
+
|
|
489
|
+
// Publish to different topics
|
|
490
|
+
await client.publish({ action: 'login' }, { subject: 'users' });
|
|
491
|
+
await client.publish({ orderId: 123 }, { subject: 'orders' });
|
|
492
|
+
await client.publish({ amount: 50 }, { subject: 'payments' });
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## Performance Tips
|
|
498
|
+
|
|
499
|
+
1. **Use subjects** for routing instead of filtering in callbacks
|
|
500
|
+
2. **Queue groups** for load balancing across multiple consumers
|
|
501
|
+
3. **Batch publishing** when sending many messages
|
|
502
|
+
4. **Remove old messages** using expiry to prevent memory issues
|
|
503
|
+
5. **WebSocket transport** is faster than long-polling (default)
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## Error Handling
|
|
508
|
+
|
|
509
|
+
```javascript
|
|
510
|
+
try {
|
|
511
|
+
const result = await client.publish({ data: 'test' });
|
|
512
|
+
if (!result.success) {
|
|
513
|
+
console.error('Publish failed:', result.error);
|
|
514
|
+
}
|
|
515
|
+
} catch (error) {
|
|
516
|
+
console.error('Connection error:', error);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Handle disconnection
|
|
520
|
+
client.socket.on('disconnect', () => {
|
|
521
|
+
console.log('Disconnected from server');
|
|
522
|
+
// Implement reconnection logic
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
client.socket.on('connect_error', (error) => {
|
|
526
|
+
console.error('Connection error:', error);
|
|
527
|
+
});
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## Browser Usage
|
|
533
|
+
|
|
534
|
+
Include Socket.IO and QueueBit client in your HTML:
|
|
535
|
+
|
|
536
|
+
```html
|
|
537
|
+
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
|
|
538
|
+
<script src="node_modules/queuebit/src/client-browser.js"></script>
|
|
539
|
+
|
|
540
|
+
<script>
|
|
541
|
+
const client = new QueueBitClient('http://localhost:3000');
|
|
542
|
+
|
|
543
|
+
client.subscribe((message) => {
|
|
544
|
+
console.log('Received:', message.data);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
client.publish({ text: 'Hello from browser!' });
|
|
548
|
+
</script>
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## NATS Compatibility
|
|
554
|
+
|
|
555
|
+
QueueBit implements NATS-like patterns:
|
|
556
|
+
|
|
557
|
+
- **Subjects**: Topic-based routing
|
|
558
|
+
- **Queue Groups**: Load-balanced delivery
|
|
559
|
+
- **At-least-once delivery**: Messages persisted until delivered
|
|
560
|
+
- **Wildcards**: Not currently supported (planned)
|
|
561
|
+
|
|
562
|
+
---
|
|
563
|
+
|
|
564
|
+
## Best Practices
|
|
565
|
+
|
|
566
|
+
1. **Use meaningful subject names**: `orders.created`, `users.login`, etc.
|
|
567
|
+
2. **Set appropriate expiry times** for temporary data
|
|
568
|
+
3. **Clean up subscriptions** when no longer needed
|
|
569
|
+
4. **Monitor queue sizes** to prevent memory issues
|
|
570
|
+
5. **Use queue groups** for scalable message processing
|
|
571
|
+
6. **Handle reconnection** in production applications
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
## License
|
|
576
|
+
|
|
577
|
+
MIT License - See LICENSE file for details
|