queen-mq 0.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.
Files changed (90) hide show
  1. package/API.md +1116 -0
  2. package/CACHE.md +519 -0
  3. package/DASHBOARD-V3.md +478 -0
  4. package/DASHBOARD.md +382 -0
  5. package/MOD_QUEUE.md +453 -0
  6. package/PARTITION_LOCKING_DESIGN.md +989 -0
  7. package/PLAN.md +707 -0
  8. package/QUERY_ANALSYS.md +72 -0
  9. package/QUEUE_BUS.md +334 -0
  10. package/README.md +1495 -0
  11. package/V2-PLAN.md +236 -0
  12. package/assets/dashboard.png +0 -0
  13. package/dashboard/.vscode/extensions.json +3 -0
  14. package/dashboard/README.md +5 -0
  15. package/dashboard/index.html +14 -0
  16. package/dashboard/package-lock.json +1458 -0
  17. package/dashboard/package.json +25 -0
  18. package/dashboard/public/vite.svg +1 -0
  19. package/dashboard/src/App.vue +29 -0
  20. package/dashboard/src/assets/styles/main.css +908 -0
  21. package/dashboard/src/assets/vue.svg +1 -0
  22. package/dashboard/src/components/cards/MetricCard.vue +298 -0
  23. package/dashboard/src/components/charts/QueueDepthChart.vue +276 -0
  24. package/dashboard/src/components/charts/QueueLagChart.vue +436 -0
  25. package/dashboard/src/components/charts/ThroughputChart.vue +302 -0
  26. package/dashboard/src/components/common/ActivityFeed.vue +251 -0
  27. package/dashboard/src/components/layout/AppHeader.vue +208 -0
  28. package/dashboard/src/components/layout/AppLayout.vue +88 -0
  29. package/dashboard/src/components/layout/AppSidebar.vue +261 -0
  30. package/dashboard/src/main.js +44 -0
  31. package/dashboard/src/router.js +54 -0
  32. package/dashboard/src/services/api.js +187 -0
  33. package/dashboard/src/services/websocket.js +167 -0
  34. package/dashboard/src/utils/constants.js +56 -0
  35. package/dashboard/src/utils/helpers.js +118 -0
  36. package/dashboard/src/views/Analytics.vue +912 -0
  37. package/dashboard/src/views/Dashboard.vue +906 -0
  38. package/dashboard/src/views/Messages.vue +437 -0
  39. package/dashboard/src/views/QueueDetail.vue +501 -0
  40. package/dashboard/src/views/Queues.vue +333 -0
  41. package/dashboard/vite.config.js +30 -0
  42. package/debug-namespace.js +110 -0
  43. package/docs/long-polling.md +159 -0
  44. package/docs/multi-server-cache-solutions.md +185 -0
  45. package/docs/performance-tuning.md +222 -0
  46. package/examples/bus-mode.js +239 -0
  47. package/examples/continuous-consumer-optimized.js +215 -0
  48. package/examples/continuous-consumer.js +159 -0
  49. package/examples/continuous-producer.js +343 -0
  50. package/examples/mixed-mode.js +277 -0
  51. package/examples/multi-server-test.js +305 -0
  52. package/examples/single.js +64 -0
  53. package/examples/smartchat-dealyed.js +42 -0
  54. package/examples/smartchat.js +52 -0
  55. package/examples/test-cache-invalidation.js +119 -0
  56. package/examples/test-cache-multi-server.js +245 -0
  57. package/examples/test-minimal-client.js +112 -0
  58. package/examples/test-queue-creation-policy.js +137 -0
  59. package/init-db.js +20 -0
  60. package/package.json +36 -0
  61. package/src/client/client.js +291 -0
  62. package/src/client/index.js +6 -0
  63. package/src/client/queenClient.js +513 -0
  64. package/src/client/utils/http.js +172 -0
  65. package/src/client/utils/loadBalancer.js +152 -0
  66. package/src/client/utils/retry.js +35 -0
  67. package/src/config.js +215 -0
  68. package/src/database/connection.js +103 -0
  69. package/src/database/poolManager.js +192 -0
  70. package/src/database/schema-v2.sql +214 -0
  71. package/src/managers/eventManager.js +59 -0
  72. package/src/managers/queueManagerOptimized.js +1512 -0
  73. package/src/managers/resourceCache.js +96 -0
  74. package/src/managers/systemEventManager.js +127 -0
  75. package/src/routes/ack.js +26 -0
  76. package/src/routes/analytics.js +812 -0
  77. package/src/routes/configure.js +46 -0
  78. package/src/routes/messages.js +298 -0
  79. package/src/routes/pop.js +85 -0
  80. package/src/routes/push.js +28 -0
  81. package/src/routes/resources.js +296 -0
  82. package/src/server.js +1286 -0
  83. package/src/services/encryptionService.js +82 -0
  84. package/src/services/evictionService.js +131 -0
  85. package/src/services/retentionService.js +129 -0
  86. package/src/services/startupSync.js +35 -0
  87. package/src/test/test.js +4521 -0
  88. package/src/utils/logger.js +44 -0
  89. package/src/utils/uuid.js +5 -0
  90. package/src/websocket/wsServer.js +221 -0
package/README.md ADDED
@@ -0,0 +1,1495 @@
1
+ # Queen - High-Performance Message Queue System
2
+
3
+ A modern, high-performance message queue system built with PostgreSQL and uWebSockets.js, featuring priority-based processing, advanced scheduling, and real-time monitoring.
4
+
5
+ ![Queen Dashboard](assets/dashboard.png)
6
+
7
+ ## ๐Ÿš€ Features
8
+
9
+ - **๐Ÿ—๏ธ Flexible Architecture**: Queues โ†’ Partitions โ†’ Messages with optional namespace/task grouping
10
+ - **โšก Priority Processing**: Queue and partition-level priorities with FIFO within partitions
11
+ - **๐Ÿ•’ Advanced Scheduling**: Delayed processing and window buffering
12
+ - **๐Ÿ”„ Reliable Processing**: Lease-based processing with automatic retry and dead letter queues
13
+ - **๐Ÿ“Š Real-time Monitoring**: WebSocket dashboard with live metrics and analytics
14
+ - **๐Ÿ”’ Message Guarantees**: ACID transactions, idempotency, and no message loss
15
+ - **๐Ÿš„ High Performance**: 10,000+ messages/second with sub-10ms latency
16
+ - **๐ŸŒ Long Polling**: Event-driven optimization for real-time message consumption
17
+ - **๐Ÿ“ฆ Batch Operations**: Efficient bulk message processing with individual and batch consumer modes
18
+ - **๐Ÿ› ๏ธ Client SDK**: Full-featured JavaScript client with retry logic and helpers
19
+
20
+ ## ๐Ÿ“‹ Table of Contents
21
+
22
+ - [Quick Start](#quick-start)
23
+ - [Architecture](#architecture)
24
+ - [Core Concepts](#core-concepts)
25
+ - [API Reference](#api-reference)
26
+ - [Client SDK](#client-sdk)
27
+ - [Dashboard](#dashboard)
28
+ - [Examples](#examples)
29
+ - [Performance](#performance)
30
+ - [Configuration](#configuration)
31
+
32
+ ## ๐Ÿƒ Quick Start
33
+
34
+ ### Prerequisites
35
+
36
+ - Node.js 22+
37
+ - PostgreSQL 12+
38
+
39
+ ### Installation
40
+
41
+ ```bash
42
+ # Clone the repository
43
+ git clone https://github.com/smartpricing/queen
44
+ cd queen
45
+
46
+ # Install dependencies
47
+ nvm use 22
48
+ npm install
49
+
50
+ # Set up environment (optional)
51
+ export PG_USER=postgres
52
+ export PG_HOST=localhost
53
+ export PG_DB=postgres
54
+ export PG_PASSWORD=postgres
55
+ export PG_PORT=5432
56
+ ```
57
+
58
+ ### Database Setup
59
+
60
+ ```bash
61
+ # Initialize the database schema
62
+ node init-db.js
63
+ ```
64
+
65
+ ### Start the Server
66
+
67
+ ```bash
68
+ # Optional: Enable encryption
69
+ export QUEEN_ENCRYPTION_KEY=$(openssl rand -hex 32)
70
+
71
+ # Start the Queen server
72
+ npm start
73
+ # Or use the startup script
74
+ ./start.sh
75
+
76
+ # Server starts on http://localhost:6632
77
+ ```
78
+
79
+ ### Basic Usage
80
+
81
+ ```javascript
82
+ import { createQueenClient } from '@dev.smartpricing/queen'
83
+
84
+ const client = createQueenClient({
85
+ baseUrl: 'http://localhost:6632'
86
+ });
87
+
88
+ // Push a message
89
+ await client.push({
90
+ items: [{
91
+ queue: 'email-queue',
92
+ partition: 'urgent',
93
+ payload: { to: 'user@example.com', subject: 'Hello!' }
94
+ }]
95
+ });
96
+
97
+ // Pop and process messages
98
+ const result = await client.pop({
99
+ queue: 'email-queue',
100
+ batch: 10,
101
+ wait: true
102
+ });
103
+
104
+ for (const message of result.messages) {
105
+ console.log('Processing:', message.data);
106
+ await client.ack(message.transactionId, 'completed');
107
+ }
108
+ ```
109
+
110
+ ## ๐Ÿ—๏ธ Architecture
111
+
112
+ ### System Overview
113
+
114
+ ```
115
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
116
+ โ”‚ Client SDK โ”‚โ”€โ”€โ”€โ–ถโ”‚ Queen Server โ”‚โ”€โ”€โ”€โ–ถโ”‚ PostgreSQL โ”‚
117
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
118
+ โ”‚
119
+ โ–ผ
120
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
121
+ โ”‚ Dashboard UI โ”‚
122
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
123
+ ```
124
+
125
+ ### Data Model
126
+
127
+ ```
128
+ Queues (with optional namespace/task grouping)
129
+ โ””โ”€โ”€ Partitions (FIFO ordering, priority-based selection)
130
+ โ””โ”€โ”€ Messages (lease-based processing)
131
+ ```
132
+
133
+ **Database Schema:**
134
+ - `queen.queues` - Top-level message containers with optional grouping
135
+ - `queen.partitions` - Subdivisions within queues where FIFO is maintained
136
+ - `queen.messages` - Individual messages with processing state
137
+
138
+ ### Key Components
139
+
140
+ - **uWebSockets.js Server**: High-performance HTTP/WebSocket server
141
+ - **Queue Manager**: Core message processing logic with optimizations
142
+ - **Resource Cache**: In-memory caching for queue/partition lookups
143
+ - **Event Manager**: Real-time notifications for long polling
144
+ - **WebSocket Server**: Live dashboard updates and monitoring
145
+
146
+ ## ๐Ÿ’ก Core Concepts
147
+
148
+ ### Queues and Partitions
149
+
150
+ **Queues** are the top-level organizational units. Each queue automatically gets a "Default" partition, and you can create additional partitions for different processing priorities or logical separation.
151
+
152
+ ```javascript
153
+ // Messages go to "Default" partition if not specified
154
+ await client.push({
155
+ items: [{ queue: 'orders', payload: { orderId: 123 } }]
156
+ });
157
+
158
+ // Explicit partition specification
159
+ await client.push({
160
+ items: [{
161
+ queue: 'orders',
162
+ partition: 'high-priority',
163
+ payload: { orderId: 456, urgent: true }
164
+ }]
165
+ });
166
+ ```
167
+
168
+ ### Priority Processing
169
+
170
+ The system supports two levels of priority:
171
+
172
+ 1. **Queue Priority**: Higher priority queues are processed first
173
+ 2. **FIFO Within Partitions**: Messages within the same partition are always processed in order
174
+ 3. **Partitions**: Partitions are now simple FIFO containers - all configuration is at the queue level
175
+
176
+ ```javascript
177
+ // Configure queue with priority
178
+ await client.configure({
179
+ queue: 'orders',
180
+ options: { priority: 10 } // Higher number = higher priority
181
+ });
182
+ ```
183
+
184
+ ### Message Lifecycle
185
+
186
+ ```
187
+ pending โ†’ processing โ†’ completed/failed โ†’ (retry) โ†’ dead_letter
188
+ ```
189
+
190
+ 1. **Pending**: Message is queued and waiting to be processed
191
+ 2. **Processing**: Message is leased to a worker (with timeout)
192
+ 3. **Completed**: Message was successfully processed
193
+ 4. **Failed**: Message processing failed (may retry based on configuration)
194
+ 5. **Dead Letter**: Message exceeded retry limits
195
+
196
+ ### Lease-Based Processing
197
+
198
+ Messages are "leased" to workers for a specific duration. If not acknowledged within the lease time, they automatically return to pending status for retry.
199
+
200
+ ```javascript
201
+ // Configure lease time (default: 300 seconds)
202
+ await client.configure({
203
+ queue: 'long-tasks',
204
+ options: { leaseTime: 600 } // 10 minutes
205
+ });
206
+ ```
207
+
208
+ ## ๐Ÿ” Advanced Concepts
209
+
210
+ ### Partition Locking
211
+
212
+ Partition locking is a critical mechanism that ensures message processing isolation and prevents duplicate processing. When a consumer retrieves messages from a partition, that partition becomes "locked" to that consumer for the duration of the lease.
213
+
214
+ #### How Partition Locking Works
215
+
216
+ 1. **Lock Acquisition**: When a consumer calls `pop()`, the system:
217
+ - Checks for available messages in unlocked partitions
218
+ - Acquires a lease on the partition(s) containing those messages
219
+ - Records the lease with an expiration time based on the queue's `leaseTime`
220
+
221
+ 2. **Lock Duration**: The partition remains locked until:
222
+ - The consumer acknowledges all messages (releases the lock)
223
+ - The lease expires (automatic release after `leaseTime` seconds)
224
+ - The consumer explicitly releases the partition
225
+
226
+ 3. **Lock Scope**:
227
+ - In **Queue Mode**: Each consumer gets a unique session, preventing any other consumer from accessing the same partition
228
+ - In **Bus Mode**: Locks are per consumer group, allowing different groups to process the same messages independently
229
+
230
+ ```javascript
231
+ // Example: Two consumers in queue mode
232
+ const consumer1 = await client.pop({ queue: 'orders' });
233
+ // Consumer 1 gets messages from partition A and locks it
234
+
235
+ const consumer2 = await client.pop({ queue: 'orders' });
236
+ // Consumer 2 gets messages from partition B (A is locked)
237
+
238
+ // After Consumer 1 acknowledges:
239
+ await client.ack(consumer1.messages[0].transactionId, 'completed');
240
+ // Partition A is now unlocked and available
241
+ ```
242
+
243
+ ### FIFO Ordering Guarantees
244
+
245
+ Queen provides strong FIFO (First-In-First-Out) ordering guarantees **within each partition**. This means:
246
+
247
+ #### Partition-Level FIFO
248
+
249
+ Messages within the same partition are always processed in the exact order they were received:
250
+
251
+ ```javascript
252
+ // These messages will be processed in order 1, 2, 3
253
+ await client.push({
254
+ items: [
255
+ { queue: 'tasks', partition: 'user-123', payload: { step: 1 } },
256
+ { queue: 'tasks', partition: 'user-123', payload: { step: 2 } },
257
+ { queue: 'tasks', partition: 'user-123', payload: { step: 3 } }
258
+ ]
259
+ });
260
+
261
+ // Consumer will always receive them in order 1, 2, 3
262
+ const result = await client.pop({ queue: 'tasks', partition: 'user-123' });
263
+ ```
264
+
265
+ #### Cross-Partition Ordering
266
+
267
+ Messages in different partitions can be processed in parallel and have no ordering guarantees relative to each other:
268
+
269
+ ```javascript
270
+ // These can be processed in any order relative to each other
271
+ await client.push({
272
+ items: [
273
+ { queue: 'tasks', partition: 'user-123', payload: { data: 'A' } },
274
+ { queue: 'tasks', partition: 'user-456', payload: { data: 'B' } }
275
+ ]
276
+ });
277
+ ```
278
+
279
+ #### Use Cases for Partitioning
280
+
281
+ - **Per-User Processing**: Use user ID as partition to ensure all user operations are processed in order
282
+ - **Per-Resource Processing**: Use resource ID to maintain operation order for specific resources
283
+ - **Priority Lanes**: Use different partitions for different priority levels
284
+
285
+ ### Consumer Groups (Bus Mode)
286
+
287
+ Consumer groups enable pub-sub messaging patterns where multiple independent consumers can process the same messages. This is ideal for scenarios like event streaming, audit logging, and analytics.
288
+
289
+ #### How Consumer Groups Work
290
+
291
+ 1. **Independent Processing**: Each consumer group maintains its own:
292
+ - Message status tracking
293
+ - Partition leases
294
+ - Retry counters
295
+ - Processing state
296
+
297
+ 2. **Message Visibility**: All consumer groups see all messages, but each group tracks which messages it has processed independently
298
+
299
+ 3. **Partition Locking per Group**: Within a consumer group, partition locking still applies to prevent duplicate processing
300
+
301
+ ```javascript
302
+ // Analytics service (Group A)
303
+ const analyticsResult = await client.pop({
304
+ queue: 'events',
305
+ consumerGroup: 'analytics-service'
306
+ });
307
+
308
+ // Audit service (Group B) - gets the same messages
309
+ const auditResult = await client.pop({
310
+ queue: 'events',
311
+ consumerGroup: 'audit-service'
312
+ });
313
+
314
+ // Billing service (Group C) - also gets the same messages
315
+ const billingResult = await client.pop({
316
+ queue: 'events',
317
+ consumerGroup: 'billing-service'
318
+ });
319
+ ```
320
+
321
+ #### Consumer Group Subscription Modes
322
+
323
+ When a consumer group is created, it can specify when to start consuming messages:
324
+
325
+ ```javascript
326
+ // Start from all existing messages
327
+ await client.pop({
328
+ queue: 'events',
329
+ consumerGroup: 'replay-service',
330
+ subscriptionMode: 'all'
331
+ });
332
+
333
+ // Start from messages created after joining
334
+ await client.pop({
335
+ queue: 'events',
336
+ consumerGroup: 'realtime-service',
337
+ subscriptionMode: 'new'
338
+ });
339
+
340
+ // Start from a specific timestamp
341
+ await client.pop({
342
+ queue: 'events',
343
+ consumerGroup: 'batch-processor',
344
+ subscriptionFrom: '2024-01-01T00:00:00Z'
345
+ });
346
+ ```
347
+
348
+ ### Namespace and Task Filtering
349
+
350
+ Queen supports cross-queue message consumption through namespace and task filtering, with full partition locking support:
351
+
352
+ #### Namespace-Based Routing
353
+
354
+ Group related queues under a namespace and consume from all of them:
355
+
356
+ ```javascript
357
+ // Configure multiple queues with the same namespace
358
+ await client.configure({
359
+ queue: 'orders-processing',
360
+ namespace: 'ecommerce',
361
+ task: 'process',
362
+ options: { leaseTime: 30 }
363
+ });
364
+
365
+ await client.configure({
366
+ queue: 'inventory-updates',
367
+ namespace: 'ecommerce',
368
+ task: 'update',
369
+ options: { leaseTime: 30 }
370
+ });
371
+
372
+ // Consume from all queues in the namespace
373
+ const messages = await client.pop({
374
+ namespace: 'ecommerce'
375
+ }, { batch: 10 });
376
+ // Gets messages from both queues, with partition locking across all
377
+ ```
378
+
379
+ #### Task-Based Routing
380
+
381
+ Filter messages by specific tasks across namespaces:
382
+
383
+ ```javascript
384
+ // Consume only 'process' tasks from the ecommerce namespace
385
+ const messages = await client.pop({
386
+ namespace: 'ecommerce',
387
+ task: 'process'
388
+ }, { batch: 5 });
389
+ ```
390
+
391
+ #### Partition Locking with Filters
392
+
393
+ When using namespace/task filtering:
394
+ - The system locks all partitions from which messages are retrieved
395
+ - Different consumers cannot access the same partitions until locks are released
396
+ - Consumer groups maintain independent locks
397
+
398
+ ```javascript
399
+ // Consumer 1: Gets messages and locks partitions A, B, C
400
+ const result1 = await client.pop({ namespace: 'ecommerce' });
401
+
402
+ // Consumer 2: Gets messages from different partitions D, E (A, B, C are locked)
403
+ const result2 = await client.pop({ namespace: 'ecommerce' });
404
+
405
+ // No partition overlap between consumers
406
+ ```
407
+
408
+ ### Concurrency Control
409
+
410
+ Queen provides several mechanisms for controlling concurrent message processing:
411
+
412
+ #### 1. Partition-Based Concurrency
413
+
414
+ Control parallelism by the number of partitions:
415
+
416
+ ```javascript
417
+ // Create multiple partitions for parallel processing
418
+ const partitions = ['worker-1', 'worker-2', 'worker-3', 'worker-4'];
419
+
420
+ // Distribute messages across partitions
421
+ await client.push({
422
+ items: messages.map((msg, i) => ({
423
+ queue: 'tasks',
424
+ partition: partitions[i % partitions.length],
425
+ payload: msg
426
+ }))
427
+ });
428
+
429
+ // Each worker processes one partition
430
+ const worker1 = await client.pop({ queue: 'tasks', partition: 'worker-1' });
431
+ const worker2 = await client.pop({ queue: 'tasks', partition: 'worker-2' });
432
+ // Workers process in parallel without interference
433
+ ```
434
+
435
+ #### 2. Lease-Based Concurrency
436
+
437
+ Automatic concurrency control through lease timeouts:
438
+
439
+ ```javascript
440
+ // Configure short leases for quick tasks
441
+ await client.configure({
442
+ queue: 'quick-tasks',
443
+ options: {
444
+ leaseTime: 30, // 30 seconds per message
445
+ retryLimit: 3 // Retry up to 3 times
446
+ }
447
+ });
448
+
449
+ // Long-running tasks need longer leases
450
+ await client.configure({
451
+ queue: 'heavy-processing',
452
+ options: {
453
+ leaseTime: 600, // 10 minutes per message
454
+ retryLimit: 1 // Retry only once
455
+ }
456
+ });
457
+ ```
458
+
459
+ #### 3. Batch Size Control
460
+
461
+ Limit concurrent processing per consumer:
462
+
463
+ ```javascript
464
+ // Each consumer processes max 5 messages at a time
465
+ const batch = await client.pop({
466
+ queue: 'tasks'
467
+ }, {
468
+ batch: 5 // Limit to 5 concurrent messages
469
+ });
470
+
471
+ // Process batch
472
+ for (const message of batch.messages) {
473
+ await processMessage(message);
474
+ await client.ack(message.transactionId, 'completed');
475
+ }
476
+ ```
477
+
478
+ ### Message Visibility and Isolation
479
+
480
+ #### Queue Mode (Default)
481
+
482
+ In queue mode, messages are consumed competitively - once a consumer gets a message, no other consumer can see it:
483
+
484
+ ```javascript
485
+ // Without consumer group - competitive consumption
486
+ const consumer1 = await client.pop({ queue: 'tasks' });
487
+ const consumer2 = await client.pop({ queue: 'tasks' });
488
+ // Each consumer gets different messages
489
+ ```
490
+
491
+ #### Bus Mode (Consumer Groups)
492
+
493
+ In bus mode, all consumer groups see all messages:
494
+
495
+ ```javascript
496
+ // With consumer groups - broadcast consumption
497
+ const service1 = await client.pop({
498
+ queue: 'events',
499
+ consumerGroup: 'service-1'
500
+ });
501
+
502
+ const service2 = await client.pop({
503
+ queue: 'events',
504
+ consumerGroup: 'service-2'
505
+ });
506
+ // Both services get the same messages
507
+ ```
508
+
509
+ #### Mixed Mode
510
+
511
+ You can combine both patterns in the same system:
512
+
513
+ ```javascript
514
+ // Competitive workers for processing
515
+ const worker = await client.pop({ queue: 'jobs' });
516
+
517
+ // Broadcast to monitoring services
518
+ const monitor = await client.pop({
519
+ queue: 'jobs',
520
+ consumerGroup: 'monitoring'
521
+ });
522
+
523
+ const analytics = await client.pop({
524
+ queue: 'jobs',
525
+ consumerGroup: 'analytics'
526
+ });
527
+ ```
528
+
529
+ ### Best Practices
530
+
531
+ #### 1. Partition Strategy
532
+
533
+ - **User-based**: Use user IDs as partitions for per-user ordering
534
+ - **Resource-based**: Use resource IDs for ordered operations on resources
535
+ - **Round-robin**: Use rotating partition names for load distribution
536
+ - **Priority-based**: Use separate partitions for different priority levels
537
+
538
+ #### 2. Consumer Group Design
539
+
540
+ - **Single Responsibility**: Each consumer group should have one clear purpose
541
+ - **Independent Processing**: Design groups to be independent of each other
542
+ - **Idempotent Operations**: Ensure operations can be safely retried
543
+
544
+ #### 3. Lease Management
545
+
546
+ - **Right-size Leases**: Set lease times slightly longer than expected processing time
547
+ - **Handle Timeouts**: Implement proper timeout handling and retries
548
+ - **Release Early**: Acknowledge messages as soon as processing completes
549
+
550
+ #### 4. Error Handling
551
+
552
+ ```javascript
553
+ try {
554
+ const messages = await client.pop({ queue: 'tasks' });
555
+
556
+ for (const message of messages.messages) {
557
+ try {
558
+ await processMessage(message);
559
+ await client.ack(message.transactionId, 'completed');
560
+ } catch (error) {
561
+ // Log error but don't ack - message will retry
562
+ console.error('Processing failed:', error);
563
+ await client.ack(message.transactionId, 'failed', error.message);
564
+ }
565
+ }
566
+ } catch (error) {
567
+ console.error('Pop failed:', error);
568
+ }
569
+ ```
570
+
571
+ ## ๐Ÿ”Œ API Reference
572
+
573
+ ### Base URL
574
+ ```
575
+ http://localhost:6632/api/v1
576
+ ```
577
+
578
+ ### Push Messages
579
+
580
+ **Endpoint:** `POST /api/v1/push`
581
+
582
+ ```javascript
583
+ {
584
+ "items": [
585
+ {
586
+ "queue": "email-queue", // Required
587
+ "partition": "urgent", // Optional (defaults to "Default")
588
+ "payload": { // Required: message data
589
+ "to": "user@example.com",
590
+ "subject": "Hello"
591
+ },
592
+ "transactionId": "uuid-here" // Optional: for idempotency
593
+ }
594
+ ]
595
+ }
596
+ ```
597
+
598
+ **Response:**
599
+ ```javascript
600
+ {
601
+ "messages": [
602
+ {
603
+ "id": "018e63b7-6165-453f-88ae-56effa177605",
604
+ "transactionId": "4dfb0478-655b-4c91-bcd9-b7acacf0400f",
605
+ "status": "queued"
606
+ }
607
+ ]
608
+ }
609
+ ```
610
+
611
+ ### Pop Messages
612
+
613
+ **From Specific Partition:**
614
+ ```
615
+ GET /api/v1/pop/queue/{queue}/partition/{partition}?wait=true&timeout=30000&batch=10
616
+ ```
617
+
618
+ **From Any Partition in Queue:**
619
+ ```
620
+ GET /api/v1/pop/queue/{queue}?wait=true&timeout=30000&batch=10
621
+ ```
622
+
623
+ **With Namespace/Task Filter:**
624
+ ```
625
+ GET /api/v1/pop?namespace=my-app&task=emails&wait=true&timeout=30000&batch=10
626
+ ```
627
+
628
+ **Response:**
629
+ ```javascript
630
+ {
631
+ "messages": [
632
+ {
633
+ "id": "018e63b7-6165-453f-88ae-56effa177605",
634
+ "transactionId": "4dfb0478-655b-4c91-bcd9-b7acacf0400f",
635
+ "queue": "email-queue",
636
+ "partition": "urgent",
637
+ "data": { "to": "user@example.com", "subject": "Hello" },
638
+ "retryCount": 0,
639
+ "priority": 10,
640
+ "createdAt": "2023-10-08T12:00:00.000Z",
641
+ "options": { "leaseTime": 300 }
642
+ }
643
+ ]
644
+ }
645
+ ```
646
+
647
+ ### Acknowledge Messages
648
+
649
+ **Single Acknowledgment:**
650
+ ```javascript
651
+ POST /api/v1/ack
652
+ {
653
+ "transactionId": "uuid",
654
+ "status": "completed", // "completed" or "failed"
655
+ "error": "optional error" // Required if status is "failed"
656
+ }
657
+ ```
658
+
659
+ **Batch Acknowledgment:**
660
+ ```javascript
661
+ POST /api/v1/ack/batch
662
+ {
663
+ "acknowledgments": [
664
+ { "transactionId": "uuid1", "status": "completed" },
665
+ { "transactionId": "uuid2", "status": "failed", "error": "Processing error" }
666
+ ]
667
+ }
668
+ ```
669
+
670
+ ### Queue Configuration
671
+
672
+ ```javascript
673
+ POST /api/v1/configure
674
+ {
675
+ "queue": "email-queue",
676
+ "partition": "urgent", // Optional (defaults to "Default")
677
+ "options": {
678
+ "leaseTime": 600, // Seconds before lease expires
679
+ "retryLimit": 5, // Max retry attempts
680
+ "priority": 10, // Partition priority (higher = first)
681
+ "delayedProcessing": 60, // Delay before message becomes available
682
+ "windowBuffer": 30 // Buffer messages for batch processing
683
+ }
684
+ }
685
+ ```
686
+
687
+ ### Analytics
688
+
689
+ ```javascript
690
+ // Get all queues overview
691
+ GET /api/v1/analytics/queues
692
+
693
+ // Get queue statistics
694
+ GET /api/v1/analytics/queue/{queueName}
695
+
696
+ // Get namespace statistics
697
+ GET /api/v1/analytics?namespace={namespace}
698
+
699
+ // Get throughput metrics
700
+ GET /api/v1/analytics/throughput
701
+
702
+ // Get queue depths
703
+ GET /api/v1/analytics/queue-depths
704
+ ```
705
+
706
+ ## ๐Ÿ“ฑ Client SDK
707
+
708
+ ### Installation
709
+
710
+ ```javascript
711
+ import { createQueenClient } from './src/client/queenClient.js';
712
+
713
+ const client = createQueenClient({
714
+ baseUrl: 'http://localhost:6632',
715
+ timeout: 30000,
716
+ retryAttempts: 3,
717
+ retryDelay: 1000
718
+ });
719
+ ```
720
+
721
+ ### Basic Operations
722
+
723
+ ```javascript
724
+ // Configure a queue
725
+ await client.configure({
726
+ queue: 'orders',
727
+ options: {
728
+ priority: 10,
729
+ leaseTime: 600,
730
+ retryLimit: 3
731
+ }
732
+ });
733
+
734
+ // Push single message
735
+ await client.push({
736
+ items: [{
737
+ queue: 'orders',
738
+ partition: 'high-priority',
739
+ payload: { orderId: 123, amount: 99.99 }
740
+ }]
741
+ });
742
+
743
+ // Push batch of messages
744
+ await client.push({
745
+ items: [
746
+ { queue: 'orders', payload: { orderId: 124 } },
747
+ { queue: 'orders', payload: { orderId: 125 } },
748
+ { queue: 'orders', payload: { orderId: 126 } }
749
+ ]
750
+ });
751
+
752
+ // Pop messages with long polling
753
+ const result = await client.pop({
754
+ queue: 'orders',
755
+ wait: true,
756
+ timeout: 30000,
757
+ batch: 10
758
+ });
759
+
760
+ // Process messages
761
+ for (const message of result.messages) {
762
+ try {
763
+ await processOrder(message.data);
764
+ await client.ack(message.transactionId, 'completed');
765
+ } catch (error) {
766
+ await client.ack(message.transactionId, 'failed', error.message);
767
+ }
768
+ }
769
+ ```
770
+
771
+ ### Consumer Pattern
772
+
773
+ The SDK provides a convenient consumer helper for continuous message processing with two modes:
774
+
775
+ #### Individual Message Processing
776
+
777
+ Process messages one by one (default behavior):
778
+
779
+ ```javascript
780
+ const stopConsumer = client.consume({
781
+ queue: 'orders',
782
+ partition: 'high-priority',
783
+ handler: async (message) => {
784
+ console.log('Processing order:', message.data.orderId);
785
+ await processOrder(message.data);
786
+ // Message is automatically acknowledged on success
787
+ },
788
+ options: {
789
+ batch: 5,
790
+ wait: true,
791
+ timeout: 30000,
792
+ stopOnError: false
793
+ }
794
+ });
795
+
796
+ // Stop the consumer when needed
797
+ // stopConsumer();
798
+ ```
799
+
800
+ #### Batch Message Processing
801
+
802
+ Process entire batches of messages at once for better performance:
803
+
804
+ ```javascript
805
+ const stopConsumer = client.consume({
806
+ queue: 'orders',
807
+ partition: 'high-priority',
808
+ handlerBatch: async (messages) => {
809
+ console.log(`Processing batch of ${messages.length} orders`);
810
+
811
+ // Process all messages in parallel
812
+ await Promise.all(messages.map(async (message) => {
813
+ console.log('Processing order:', message.data.orderId);
814
+ await processOrder(message.data);
815
+ }));
816
+
817
+ // Or process sequentially if needed
818
+ // for (const message of messages) {
819
+ // await processOrder(message.data);
820
+ // }
821
+
822
+ // All messages are automatically batch-acknowledged on success
823
+ },
824
+ options: {
825
+ batch: 10, // Larger batches for better throughput
826
+ wait: true,
827
+ timeout: 30000,
828
+ stopOnError: false
829
+ }
830
+ });
831
+ ```
832
+
833
+ **Key Benefits of Batch Processing:**
834
+ - **Higher Throughput**: Process multiple messages simultaneously
835
+ - **Efficient Acknowledgments**: Single batch ACK instead of individual ACKs
836
+ - **Atomic Processing**: Either the entire batch succeeds or fails together
837
+ - **Reduced Network Overhead**: Fewer round trips to the server
838
+
839
+ **Important Notes:**
840
+ - Use either `handler` OR `handlerBatch`, not both
841
+ - In batch mode, if processing fails, all messages in the batch are marked as failed
842
+ - Batch size is controlled by the `batch` option (default: 1)
843
+
844
+ ### Advanced Features
845
+
846
+ ```javascript
847
+ // Pop with namespace filter (cross-queue priority)
848
+ const result = await client.pop({
849
+ namespace: 'ecommerce',
850
+ batch: 10,
851
+ wait: true
852
+ });
853
+
854
+ // Batch acknowledgment
855
+ await client.ackBatch([
856
+ { transactionId: 'uuid1', status: 'completed' },
857
+ { transactionId: 'uuid2', status: 'failed', error: 'Invalid data' }
858
+ ]);
859
+
860
+ // Message management
861
+ const messages = await client.messages.list({
862
+ queue: 'orders',
863
+ status: 'failed',
864
+ limit: 100
865
+ });
866
+
867
+ await client.messages.retry('transaction-id');
868
+ await client.messages.moveToDLQ('transaction-id');
869
+ ```
870
+
871
+ ## ๐Ÿ“Š Dashboard
872
+
873
+ The Queen system includes a comprehensive web dashboard for monitoring and management.
874
+
875
+ ### Accessing the Dashboard
876
+
877
+ 1. **Start the server**: `npm start`
878
+ 2. **Open dashboard**: Navigate to `http://localhost:6632` in your browser
879
+ 3. **WebSocket connection**: The dashboard connects via WebSocket for real-time updates
880
+
881
+ ### Dashboard Features
882
+
883
+ #### 1. **System Overview**
884
+ - **Real-time Metrics**: Total messages, processing rate, system health
885
+ - **Queue Summary**: Active queues, pending messages, processing status
886
+ - **Performance Indicators**: Throughput, latency, error rates
887
+
888
+ #### 2. **Queue Management**
889
+ - **Queue List**: All queues with current status and message counts
890
+ - **Partition View**: Partitions within each queue with priority indicators
891
+ - **Message Counts**: Pending, processing, completed, failed, and dead letter counts
892
+ - **Priority Visualization**: Color-coded priority levels
893
+
894
+ #### 3. **Real-time Monitoring**
895
+ - **Live Updates**: WebSocket-powered real-time data updates
896
+ - **Throughput Charts**: Messages per second over time
897
+ - **Queue Depth Graphs**: Pending message counts with trend analysis
898
+ - **Lag Monitoring**: Processing time and queue lag metrics
899
+
900
+ #### 4. **Message Browser**
901
+ - **Message Search**: Filter by queue, partition, status, or time range
902
+ - **Message Details**: Full payload, metadata, and processing history
903
+ - **Retry Management**: Manually retry failed messages
904
+ - **Dead Letter Queue**: View and manage messages that exceeded retry limits
905
+
906
+ #### 5. **Analytics Dashboard**
907
+ - **Performance Metrics**: Detailed throughput and latency statistics
908
+ - **Queue Analytics**: Per-queue performance and usage patterns
909
+ - **Historical Data**: Trends and patterns over time
910
+ - **System Health**: Database connections, memory usage, error rates
911
+
912
+ #### 6. **Configuration Management**
913
+ - **Queue Configuration**: View and modify queue settings
914
+ - **Partition Settings**: Priority, lease time, retry limits
915
+ - **System Settings**: Global configuration options
916
+
917
+ ### Dashboard Components
918
+
919
+ The dashboard is built with Vue.js and includes:
920
+
921
+ ```
922
+ dashboard/
923
+ โ”œโ”€โ”€ src/
924
+ โ”‚ โ”œโ”€โ”€ components/
925
+ โ”‚ โ”‚ โ”œโ”€โ”€ charts/ # Chart components
926
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ QueueDepthChart.vue
927
+ โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ QueueLagChart.vue
928
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ ThroughputChart.vue
929
+ โ”‚ โ”‚ โ”œโ”€โ”€ cards/ # Metric cards
930
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ MetricCard.vue
931
+ โ”‚ โ”‚ โ”œโ”€โ”€ common/ # Shared components
932
+ โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ ActivityFeed.vue
933
+ โ”‚ โ”‚ โ””โ”€โ”€ layout/ # Layout components
934
+ โ”‚ โ”‚ โ”œโ”€โ”€ AppHeader.vue
935
+ โ”‚ โ”‚ โ”œโ”€โ”€ AppLayout.vue
936
+ โ”‚ โ”‚ โ””โ”€โ”€ AppSidebar.vue
937
+ โ”‚ โ”œโ”€โ”€ views/ # Main pages
938
+ โ”‚ โ”‚ โ”œโ”€โ”€ Dashboard.vue # System overview
939
+ โ”‚ โ”‚ โ”œโ”€โ”€ Queues.vue # Queue management
940
+ โ”‚ โ”‚ โ”œโ”€โ”€ QueueDetail.vue # Individual queue details
941
+ โ”‚ โ”‚ โ”œโ”€โ”€ Messages.vue # Message browser
942
+ โ”‚ โ”‚ โ””โ”€โ”€ Analytics.vue # Analytics dashboard
943
+ โ”‚ โ””โ”€โ”€ services/
944
+ โ”‚ โ”œโ”€โ”€ api.js # API client
945
+ โ”‚ โ””โ”€โ”€ websocket.js # WebSocket connection
946
+ ```
947
+
948
+ ### WebSocket API
949
+
950
+ The dashboard connects via WebSocket for real-time updates:
951
+
952
+ ```javascript
953
+ // Connect to dashboard WebSocket
954
+ const ws = new WebSocket('ws://localhost:6632/ws/dashboard');
955
+
956
+ // Receive real-time updates
957
+ ws.onmessage = (event) => {
958
+ const { event: eventType, data } = JSON.parse(event.data);
959
+
960
+ switch (eventType) {
961
+ case 'queue.depth.updated':
962
+ updateQueueDepth(data);
963
+ break;
964
+ case 'message.processed':
965
+ updateThroughput(data);
966
+ break;
967
+ case 'system.stats':
968
+ updateSystemStats(data);
969
+ break;
970
+ }
971
+ };
972
+ ```
973
+
974
+ ## ๐Ÿ“š Examples
975
+
976
+ ### Basic Email Queue
977
+
978
+ ```javascript
979
+ // Configure email queue with priority
980
+ await client.configure({
981
+ queue: 'emails-urgent',
982
+ options: { priority: 10, leaseTime: 300 }
983
+ });
984
+
985
+ await client.configure({
986
+ queue: 'emails-normal',
987
+ options: { priority: 5, leaseTime: 300 }
988
+ });
989
+
990
+ // Send urgent email
991
+ await client.push({
992
+ items: [{
993
+ queue: 'emails',
994
+ partition: 'urgent',
995
+ payload: {
996
+ to: 'admin@company.com',
997
+ subject: 'System Alert',
998
+ body: 'Critical system issue detected'
999
+ }
1000
+ }]
1001
+ });
1002
+
1003
+ // Process emails (urgent emails processed first)
1004
+ const result = await client.pop({
1005
+ queue: 'emails',
1006
+ batch: 10,
1007
+ wait: true
1008
+ });
1009
+ ```
1010
+
1011
+ ### Delayed Job Processing
1012
+
1013
+ ```javascript
1014
+ // Configure queue with delayed processing
1015
+ await client.configure({
1016
+ queue: 'scheduled-jobs',
1017
+ options: {
1018
+ delayedProcessing: 3600, // 1 hour delay
1019
+ priority: 5
1020
+ }
1021
+ });
1022
+
1023
+ // Schedule a job for later processing
1024
+ await client.push({
1025
+ items: [{
1026
+ queue: 'scheduled-jobs',
1027
+ partition: 'daily-reports',
1028
+ payload: {
1029
+ reportType: 'daily-sales',
1030
+ date: '2023-10-08',
1031
+ recipients: ['manager@company.com']
1032
+ }
1033
+ }]
1034
+ });
1035
+
1036
+ // Job will not be available for processing until 1 hour later
1037
+ ```
1038
+
1039
+ ### Batch Processing with Window Buffer
1040
+
1041
+ ```javascript
1042
+ // Configure for batch processing
1043
+ await client.configure({
1044
+ queue: 'analytics',
1045
+ options: {
1046
+ windowBuffer: 60, // Wait 60 seconds to batch messages
1047
+ priority: 3
1048
+ }
1049
+ });
1050
+
1051
+ // Send multiple events
1052
+ for (let i = 0; i < 100; i++) {
1053
+ await client.push({
1054
+ items: [{
1055
+ queue: 'analytics',
1056
+ partition: 'events',
1057
+ payload: { userId: i, action: 'page_view', timestamp: Date.now() }
1058
+ }]
1059
+ });
1060
+ }
1061
+
1062
+ // Messages will be held for 60 seconds to allow batching
1063
+ // Then all messages become available at once for efficient processing
1064
+ ```
1065
+
1066
+ ### Multi-Queue Processing with Priorities
1067
+
1068
+ ```javascript
1069
+ // Set up multiple queues with different priorities
1070
+ const queues = [
1071
+ { name: 'critical-alerts', priority: 100 },
1072
+ { name: 'user-notifications', priority: 50 },
1073
+ { name: 'background-tasks', priority: 10 }
1074
+ ];
1075
+
1076
+ for (const queue of queues) {
1077
+ await client.configure({
1078
+ queue: queue.name,
1079
+ options: { priority: queue.priority }
1080
+ });
1081
+ }
1082
+
1083
+ // Consumer that processes all queues by priority
1084
+ const stopConsumer = client.consume({
1085
+ namespace: 'my-app', // Process all queues in namespace by priority
1086
+ handler: async (message) => {
1087
+ console.log(`Processing ${message.queue}: ${message.data.type}`);
1088
+ await processMessage(message);
1089
+ },
1090
+ options: { batch: 5, wait: true }
1091
+ });
1092
+ ```
1093
+
1094
+ ### High-Throughput Batch Processing
1095
+
1096
+ ```javascript
1097
+ // Configure queue for high-throughput batch processing
1098
+ await client.configure({
1099
+ queue: 'data-processing',
1100
+ options: {
1101
+ priority: 5,
1102
+ leaseTime: 600, // 10 minutes for batch processing
1103
+ windowBuffer: 30 // Buffer messages for 30 seconds
1104
+ }
1105
+ });
1106
+
1107
+ // High-performance batch consumer
1108
+ const stopConsumer = client.consume({
1109
+ queue: 'data-processing',
1110
+ partition: 'analytics',
1111
+ handlerBatch: async (messages) => {
1112
+ const startTime = Date.now();
1113
+ console.log(`Processing batch of ${messages.length} analytics events`);
1114
+
1115
+ try {
1116
+ // Extract all payloads for batch processing
1117
+ const events = messages.map(msg => ({
1118
+ id: msg.transactionId,
1119
+ ...msg.data
1120
+ }));
1121
+
1122
+ // Process entire batch efficiently
1123
+ await processAnalyticsBatch(events);
1124
+
1125
+ const processingTime = Date.now() - startTime;
1126
+ console.log(`โœ… Batch processed in ${processingTime}ms`);
1127
+
1128
+ } catch (error) {
1129
+ console.error('Batch processing failed:', error);
1130
+ throw error; // Will mark all messages as failed
1131
+ }
1132
+ },
1133
+ options: {
1134
+ batch: 50, // Process up to 50 messages at once
1135
+ wait: true, // Use long polling
1136
+ timeout: 30000,
1137
+ stopOnError: false
1138
+ }
1139
+ });
1140
+
1141
+ async function processAnalyticsBatch(events) {
1142
+ // Example: Bulk insert to database
1143
+ await database.analytics.insertMany(events);
1144
+
1145
+ // Example: Send to external analytics service
1146
+ await analyticsService.sendBatch(events);
1147
+
1148
+ // Example: Update aggregated metrics
1149
+ await updateMetrics(events);
1150
+ }
1151
+ ```
1152
+
1153
+ ## โšก Performance
1154
+
1155
+ ### Benchmarks
1156
+
1157
+ - **Throughput**: 10,000+ messages/second
1158
+ - **Latency**: < 10ms for immediate pop operations
1159
+ - **Concurrent Connections**: 1,000+ long polling connections
1160
+ - **Database**: Optimized for PostgreSQL with proper indexing
1161
+
1162
+ ### Optimization Features
1163
+
1164
+ - **Connection Pooling**: Efficient database connection management
1165
+ - **Resource Caching**: In-memory cache for queue/partition lookups
1166
+ - **Batch Operations**: Bulk insert/update for high throughput
1167
+ - **Optimized Queries**: Carefully crafted SQL with proper indexes
1168
+ - **Event-Driven Architecture**: Minimal polling overhead
1169
+
1170
+ ### Performance Tuning
1171
+
1172
+ ```javascript
1173
+ // Environment variables for performance tuning
1174
+ export DB_POOL_SIZE=20 // Database connection pool size
1175
+ export DB_IDLE_TIMEOUT=30000 // Connection idle timeout
1176
+ export DB_CONNECTION_TIMEOUT=2000 // Connection establishment timeout
1177
+ ```
1178
+
1179
+ ## ๐Ÿ”’ Enterprise Features
1180
+
1181
+ Queen includes three powerful enterprise features for production deployments:
1182
+
1183
+ ### 1. Encryption
1184
+ Protect sensitive data with AES-256-GCM encryption at the queue level.
1185
+
1186
+ **Setup:**
1187
+ ```bash
1188
+ # Set encryption key (64 hex characters = 32 bytes)
1189
+ export QUEEN_ENCRYPTION_KEY=$(openssl rand -hex 32)
1190
+ ```
1191
+
1192
+ **Configuration:**
1193
+ ```javascript
1194
+ await client.configure({
1195
+ queue: 'sensitive-data',
1196
+ options: {
1197
+ encryptionEnabled: true
1198
+ }
1199
+ });
1200
+ ```
1201
+
1202
+ ### 2. Message Retention
1203
+ Automatically clean up old messages to prevent storage bloat.
1204
+
1205
+ **Configuration:**
1206
+ ```javascript
1207
+ await client.configure({
1208
+ queue: 'temp-queue',
1209
+ options: {
1210
+ retentionSeconds: 3600, // Delete pending after 1 hour
1211
+ completedRetentionSeconds: 300, // Delete completed after 5 minutes
1212
+ retentionEnabled: true
1213
+ }
1214
+ });
1215
+ ```
1216
+
1217
+ **Environment:**
1218
+ ```bash
1219
+ export RETENTION_INTERVAL=300000 # Cleanup interval in milliseconds
1220
+ ```
1221
+
1222
+ ### 3. Message Eviction
1223
+ Enforce SLAs by automatically evicting messages that wait too long.
1224
+
1225
+ **Configuration:**
1226
+ ```javascript
1227
+ await client.configure({
1228
+ queue: 'time-sensitive',
1229
+ options: {
1230
+ maxWaitTimeSeconds: 60 // Evict messages older than 1 minute
1231
+ }
1232
+ });
1233
+ ```
1234
+
1235
+ **Environment:**
1236
+ ```bash
1237
+ export EVICTION_INTERVAL=60000 # Check interval in milliseconds
1238
+ ```
1239
+
1240
+ ### Combined Example
1241
+ ```javascript
1242
+ await client.configure({
1243
+ queue: 'production-queue',
1244
+ options: {
1245
+ // Encryption
1246
+ encryptionEnabled: true,
1247
+
1248
+ // Retention
1249
+ retentionSeconds: 86400,
1250
+ completedRetentionSeconds: 3600,
1251
+ retentionEnabled: true,
1252
+
1253
+ // Eviction
1254
+ maxWaitTimeSeconds: 600,
1255
+
1256
+ // Standard options
1257
+ priority: 10,
1258
+ leaseTime: 300
1259
+ }
1260
+ });
1261
+ ```
1262
+
1263
+ ## โš™๏ธ Configuration
1264
+
1265
+ ### Environment Variables
1266
+
1267
+ All configuration values have sensible defaults and can be overridden using environment variables. Configuration is centralized in `src/config.js`.
1268
+
1269
+ #### Server Configuration
1270
+
1271
+ ```bash
1272
+ # Server basics
1273
+ PORT=6632 # Server port (default: 6632)
1274
+ HOST=0.0.0.0 # Server host (default: 0.0.0.0)
1275
+ WORKER_ID=worker-1 # Worker identifier (default: worker-${process.pid})
1276
+ APP_NAME=queen-uws # Application name for database connections
1277
+
1278
+ # CORS settings
1279
+ CORS_MAX_AGE=86400 # CORS max age in seconds (default: 86400 = 24 hours)
1280
+ CORS_ALLOWED_ORIGINS=* # Allowed origins (default: *)
1281
+ CORS_ALLOWED_METHODS=GET,POST,PUT,DELETE,OPTIONS # Allowed methods
1282
+ CORS_ALLOWED_HEADERS=Content-Type,Authorization # Allowed headers
1283
+ ```
1284
+
1285
+ #### Database Configuration
1286
+
1287
+ ```bash
1288
+ # Connection settings
1289
+ PG_USER=postgres # PostgreSQL user (default: postgres)
1290
+ PG_HOST=localhost # PostgreSQL host (default: localhost)
1291
+ PG_DB=postgres # PostgreSQL database (default: postgres)
1292
+ PG_PASSWORD=postgres # PostgreSQL password (default: postgres)
1293
+ PG_PORT=5432 # PostgreSQL port (default: 5432)
1294
+
1295
+ # Connection pool settings
1296
+ DB_POOL_SIZE=20 # Max pool size (default: 20)
1297
+ DB_IDLE_TIMEOUT=30000 # Idle connection timeout in ms (default: 30000)
1298
+ DB_CONNECTION_TIMEOUT=2000 # Connection timeout in ms (default: 2000)
1299
+ DB_STATEMENT_TIMEOUT=30000 # Statement timeout in ms (default: 30000)
1300
+ DB_QUERY_TIMEOUT=30000 # Query timeout in ms (default: 30000)
1301
+ DB_MAX_RETRIES=3 # Max retry attempts for queries (default: 3)
1302
+ ```
1303
+
1304
+ #### Queue Processing Configuration
1305
+
1306
+ ```bash
1307
+ # Pop operation defaults
1308
+ DEFAULT_TIMEOUT=30000 # Default pop timeout in ms (default: 30000)
1309
+ MAX_TIMEOUT=60000 # Maximum pop timeout in ms (default: 60000)
1310
+ DEFAULT_BATCH_SIZE=1 # Default batch size for pop (default: 1)
1311
+ BATCH_INSERT_SIZE=1000 # Batch size for bulk inserts (default: 1000)
1312
+
1313
+ # Long polling
1314
+ QUEUE_POLL_INTERVAL=100 # Poll interval in ms (default: 100)
1315
+ QUEUE_POLL_INTERVAL_FILTERED=1000 # Poll interval for filtered pops (default: 1000)
1316
+
1317
+ # Queue defaults
1318
+ DEFAULT_LEASE_TIME=300 # Default lease time in seconds (default: 300 = 5 minutes)
1319
+ DEFAULT_RETRY_LIMIT=3 # Default retry limit (default: 3)
1320
+ DEFAULT_RETRY_DELAY=1000 # Default retry delay in ms (default: 1000)
1321
+ DEFAULT_MAX_SIZE=10000 # Default max queue size (default: 10000)
1322
+ DEFAULT_TTL=3600 # Default TTL in seconds (default: 3600 = 1 hour)
1323
+ DEFAULT_PRIORITY=0 # Default queue priority (default: 0)
1324
+ DEFAULT_DELAYED_PROCESSING=0 # Default delayed processing in seconds (default: 0)
1325
+ DEFAULT_WINDOW_BUFFER=0 # Default window buffer in seconds (default: 0)
1326
+
1327
+ # Dead Letter Queue
1328
+ DEFAULT_DLQ_ENABLED=false # Enable DLQ by default (default: false)
1329
+ DEFAULT_DLQ_AFTER_MAX_RETRIES=false # Move to DLQ after max retries (default: false)
1330
+
1331
+ # Retention
1332
+ DEFAULT_RETENTION_SECONDS=0 # Default retention for all messages (default: 0 = disabled)
1333
+ DEFAULT_COMPLETED_RETENTION_SECONDS=0 # Retention for completed messages (default: 0)
1334
+ DEFAULT_RETENTION_ENABLED=false # Enable retention by default (default: false)
1335
+
1336
+ # Eviction
1337
+ DEFAULT_MAX_WAIT_TIME_SECONDS=0 # Max wait time before eviction (default: 0 = disabled)
1338
+ ```
1339
+
1340
+ #### Background Jobs Configuration
1341
+
1342
+ ```bash
1343
+ # Job intervals
1344
+ LEASE_RECLAIM_INTERVAL=5000 # Lease reclamation interval in ms (default: 5000)
1345
+ RETENTION_INTERVAL=300000 # Retention check interval in ms (default: 300000 = 5 minutes)
1346
+ RETENTION_BATCH_SIZE=1000 # Retention batch size (default: 1000)
1347
+ PARTITION_CLEANUP_DAYS=7 # Days before cleaning empty partitions (default: 7)
1348
+ EVICTION_INTERVAL=60000 # Eviction check interval in ms (default: 60000 = 1 minute)
1349
+ EVICTION_BATCH_SIZE=1000 # Eviction batch size (default: 1000)
1350
+
1351
+ # WebSocket updates
1352
+ QUEUE_DEPTH_UPDATE_INTERVAL=5000 # Queue depth update interval (default: 5000)
1353
+ SYSTEM_STATS_UPDATE_INTERVAL=10000 # System stats update interval (default: 10000)
1354
+ ```
1355
+
1356
+ #### WebSocket Configuration
1357
+
1358
+ ```bash
1359
+ # WebSocket settings
1360
+ WS_COMPRESSION=0 # Compression level (default: 0 = disabled)
1361
+ WS_MAX_PAYLOAD_LENGTH=16384 # Max payload length in bytes (default: 16384 = 16KB)
1362
+ WS_IDLE_TIMEOUT=60 # Idle timeout in seconds (default: 60)
1363
+ WS_MAX_CONNECTIONS=1000 # Max concurrent connections (default: 1000)
1364
+ WS_HEARTBEAT_INTERVAL=30000 # Heartbeat interval in ms (default: 30000)
1365
+ ```
1366
+
1367
+ #### Encryption Configuration
1368
+
1369
+ ```bash
1370
+ # Encryption settings
1371
+ QUEEN_ENCRYPTION_KEY=<64-hex> # 32-byte key as 64 hex characters
1372
+ # Generate with: openssl rand -hex 32
1373
+ # Required for encryption features
1374
+ ```
1375
+
1376
+ #### Client SDK Configuration
1377
+
1378
+ ```bash
1379
+ # Client defaults
1380
+ QUEEN_BASE_URL=http://localhost:6632 # Default server URL
1381
+ CLIENT_RETRY_ATTEMPTS=3 # Default retry attempts (default: 3)
1382
+ CLIENT_RETRY_DELAY=1000 # Default retry delay in ms (default: 1000)
1383
+ CLIENT_RETRY_BACKOFF=2 # Retry backoff multiplier (default: 2)
1384
+ CLIENT_POOL_SIZE=10 # Client connection pool size (default: 10)
1385
+ CLIENT_REQUEST_TIMEOUT=30000 # Request timeout in ms (default: 30000)
1386
+ ```
1387
+
1388
+ #### API Configuration
1389
+
1390
+ ```bash
1391
+ # Pagination
1392
+ API_DEFAULT_LIMIT=100 # Default page size (default: 100)
1393
+ API_MAX_LIMIT=1000 # Maximum page size (default: 1000)
1394
+ API_DEFAULT_OFFSET=0 # Default offset (default: 0)
1395
+ ```
1396
+
1397
+ #### Analytics Configuration
1398
+
1399
+ ```bash
1400
+ # Analytics settings
1401
+ ANALYTICS_RECENT_HOURS=24 # Hours to consider for recent stats (default: 24)
1402
+ ANALYTICS_MIN_COMPLETED=5 # Min completed messages for stats (default: 5)
1403
+ RECENT_MESSAGE_WINDOW=60 # Recent message window in seconds (default: 60)
1404
+ RELATED_MESSAGE_WINDOW=3600 # Related message window in seconds (default: 3600)
1405
+ MAX_RELATED_MESSAGES=10 # Max related messages to return (default: 10)
1406
+ ```
1407
+
1408
+ #### Monitoring Configuration
1409
+
1410
+ ```bash
1411
+ # Performance monitoring
1412
+ ENABLE_REQUEST_COUNTING=true # Enable request counting (default: true)
1413
+ ENABLE_MESSAGE_COUNTING=true # Enable message counting (default: true)
1414
+ METRICS_ENDPOINT_ENABLED=true # Enable /metrics endpoint (default: true)
1415
+ HEALTH_CHECK_ENABLED=true # Enable /health endpoint (default: true)
1416
+ ```
1417
+
1418
+ #### Logging Configuration
1419
+
1420
+ ```bash
1421
+ # Logging settings
1422
+ ENABLE_LOGGING=true # Enable logging (default: true)
1423
+ LOG_LEVEL=info # Log level (default: info)
1424
+ LOG_FORMAT=json # Log format (default: json)
1425
+ LOG_TIMESTAMP=true # Include timestamps (default: true)
1426
+ ```
1427
+
1428
+ ### Queue Options
1429
+
1430
+ ```javascript
1431
+ {
1432
+ // Standard Options
1433
+ "leaseTime": 300, // Seconds before message lease expires
1434
+ "retryLimit": 3, // Maximum retry attempts
1435
+ "priority": 0, // Queue/partition priority (higher = first)
1436
+ "delayedProcessing": 0, // Delay in seconds before message is available
1437
+ "windowBuffer": 0, // Buffer time in seconds for batching
1438
+ "dlqAfterMaxRetries": true, // Move to dead letter queue after max retries
1439
+
1440
+ // Encryption (Queue-level)
1441
+ "encryptionEnabled": false, // Enable AES-256-GCM encryption for this queue
1442
+
1443
+ // Retention (Partition-level)
1444
+ "retentionSeconds": 0, // Delete pending messages after X seconds (0 = disabled)
1445
+ "completedRetentionSeconds": 0, // Delete completed/failed messages after X seconds
1446
+ "partitionRetentionSeconds": 0, // Delete empty partitions after X seconds
1447
+ "retentionEnabled": false, // Enable retention for this partition
1448
+
1449
+ // Eviction (Queue-level)
1450
+ "maxWaitTimeSeconds": 0 // Evict messages older than X seconds (0 = disabled)
1451
+ }
1452
+ ```
1453
+
1454
+ ## ๐Ÿงช Testing
1455
+
1456
+ ### Run Core Feature Tests
1457
+
1458
+ ```bash
1459
+ # Start the server
1460
+ npm start
1461
+
1462
+ # Run comprehensive test suite
1463
+ node src/test/core-features-test.js
1464
+
1465
+ # Run full test suite (more detailed)
1466
+ node src/test/comprehensive-test.js
1467
+ ```
1468
+
1469
+ ### Test Results
1470
+
1471
+ The test suite verifies:
1472
+ - โœ… Single and batch message push
1473
+ - โœ… Queue configuration and options
1474
+ - โœ… Pop operations (specific partition and queue-level)
1475
+ - โœ… Delayed processing (2+ second delays)
1476
+ - โœ… Partition priority ordering
1477
+ - โœ… Consumer pattern with automatic acknowledgment
1478
+ - โœ… Message acknowledgment and retry logic
1479
+ - โœ… FIFO ordering within partitions
1480
+
1481
+ ## ๐Ÿค Contributing
1482
+
1483
+ 1. Fork the repository
1484
+ 2. Create a feature branch
1485
+ 3. Make your changes
1486
+ 4. Run the test suite
1487
+ 5. Submit a pull request
1488
+
1489
+ ## ๐Ÿ“„ License
1490
+
1491
+ MIT License - see LICENSE file for details.
1492
+
1493
+ ---
1494
+
1495
+ **Queen Message Queue System** - Built for performance, reliability, and scalability. ๐Ÿš€