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/MOD_QUEUE.md ADDED
@@ -0,0 +1,453 @@
1
+ # Queue-Only Configuration Modification Plan
2
+
3
+ ## Overview
4
+ This document outlines the plan to simplify the Queen message queue system by moving all configuration options to the queue level, making partitions pure FIFO containers without individual settings.
5
+
6
+ ## Current Problem
7
+ Configuration options are currently split between queues and partitions, creating:
8
+ - Confusion about where to set options
9
+ - Inconsistent API behavior
10
+ - Unused configuration values (e.g., leaseTime is configured but hardcoded to 300s)
11
+ - Complex mental model
12
+
13
+ ## Solution: Queue-Only Configuration
14
+ Move ALL configuration options to the queue level. Partitions become simple FIFO containers with only a name and reference to their parent queue.
15
+
16
+ ---
17
+
18
+ ## 1. Database Schema Changes
19
+
20
+ ### 1.1 Modify `queen.queues` Table
21
+ Add all configuration columns currently stored in partition options:
22
+
23
+ ```sql
24
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS lease_time INTEGER DEFAULT 300;
25
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS retry_limit INTEGER DEFAULT 3;
26
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS retry_delay INTEGER DEFAULT 1000;
27
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS max_size INTEGER DEFAULT 10000;
28
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS ttl INTEGER DEFAULT 3600;
29
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS dead_letter_queue BOOLEAN DEFAULT FALSE;
30
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS dlq_after_max_retries BOOLEAN DEFAULT FALSE;
31
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS delayed_processing INTEGER DEFAULT 0;
32
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS window_buffer INTEGER DEFAULT 0;
33
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS retention_seconds INTEGER DEFAULT 0;
34
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS completed_retention_seconds INTEGER DEFAULT 0;
35
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS retention_enabled BOOLEAN DEFAULT FALSE;
36
+
37
+ -- Note: These already exist:
38
+ -- priority INTEGER DEFAULT 0
39
+ -- encryption_enabled BOOLEAN DEFAULT FALSE
40
+ -- max_wait_time_seconds INTEGER DEFAULT 0
41
+ ```
42
+
43
+ ### 1.2 Simplify `queen.partitions` Table
44
+ Remove configuration-related columns:
45
+
46
+ ```sql
47
+ ALTER TABLE queen.partitions
48
+ DROP COLUMN IF EXISTS options,
49
+ DROP COLUMN IF EXISTS priority;
50
+
51
+ -- Final structure:
52
+ -- id UUID PRIMARY KEY
53
+ -- queue_id UUID REFERENCES queen.queues(id)
54
+ -- name VARCHAR(255) NOT NULL DEFAULT 'Default'
55
+ -- created_at TIMESTAMP DEFAULT NOW()
56
+ -- last_activity TIMESTAMP DEFAULT NOW()
57
+ ```
58
+
59
+ ---
60
+
61
+ ## 2. Code Modifications Required
62
+
63
+ ### 2.1 Core Manager Changes
64
+
65
+ #### `src/managers/queueManagerOptimized.js` (MAJOR CHANGES)
66
+
67
+ **Line 18-57: ensureResources function**
68
+ - Remove `options` from partition query (line 40)
69
+ - Remove `partitionOptions` from cache structure (line 48)
70
+ - Update to fetch queue configuration instead
71
+
72
+ **Lines 200-364: popMessages function**
73
+ - Lines 214-239: Update partition-specific pop query to use queue options
74
+ - Line 318: Use queue's `lease_time` instead of hardcoded 300
75
+ - Line 355: Remove options from message response
76
+
77
+ **Lines 366-431: popMessagesWithFilters function**
78
+ - Line 420: Use queue's `lease_time` instead of hardcoded 300
79
+
80
+ **Lines 483-539: acknowledgeMessage function**
81
+ - Lines 500-509: Query queue options instead of partition options for retry logic
82
+
83
+ **Lines 586-692: Configuration functions**
84
+ - Remove `configureQueueOnly` function (no longer needed)
85
+ - Rewrite `configureQueue` to only update queue-level settings
86
+ - Remove partition parameter handling
87
+
88
+ ### 2.2 Route Changes
89
+
90
+ #### `src/routes/configure.js` (COMPLETE REWRITE)
91
+ ```javascript
92
+ export const createConfigureRoute = (queueManager) => {
93
+ return async (body) => {
94
+ const { queue, namespace, task, options = {} } = body;
95
+
96
+ if (!queue) {
97
+ throw new Error('queue is required');
98
+ }
99
+
100
+ const validOptions = {
101
+ leaseTime: options.leaseTime || 300,
102
+ maxSize: options.maxSize || 10000,
103
+ ttl: options.ttl || 3600,
104
+ retryLimit: options.retryLimit || 3,
105
+ retryDelay: options.retryDelay || 1000,
106
+ deadLetterQueue: options.deadLetterQueue || false,
107
+ dlqAfterMaxRetries: options.dlqAfterMaxRetries || false,
108
+ priority: options.priority || 0,
109
+ delayedProcessing: options.delayedProcessing || 0,
110
+ windowBuffer: options.windowBuffer || 0,
111
+ retentionSeconds: options.retentionSeconds || 0,
112
+ completedRetentionSeconds: options.completedRetentionSeconds || 0,
113
+ retentionEnabled: options.retentionEnabled || false,
114
+ encryptionEnabled: options.encryptionEnabled,
115
+ maxWaitTimeSeconds: options.maxWaitTimeSeconds
116
+ };
117
+
118
+ const result = await queueManager.configureQueue(queue, validOptions, namespace, task);
119
+
120
+ return {
121
+ queue,
122
+ namespace,
123
+ task,
124
+ configured: true,
125
+ options: result.options
126
+ };
127
+ };
128
+ };
129
+ ```
130
+
131
+ #### `src/routes/resources.js` (MINOR CHANGES)
132
+ - Line 152: Remove `p.options` from partition query
133
+ - Line 191: Remove `options` from partition response
134
+
135
+ #### `src/routes/messages.js` (MINOR CHANGES)
136
+ - Line 97: Remove `p.options as partition_options` from query
137
+ - Line 127: Remove `partitionOptions` from response
138
+
139
+ ### 2.3 Service Changes
140
+
141
+ #### `src/services/retentionService.js`
142
+ - Lines 83-88: Query queue options instead of partition options
143
+ ```sql
144
+ SELECT q.id, q.name, q.retention_enabled, q.retention_seconds,
145
+ q.completed_retention_seconds
146
+ FROM queen.queues q
147
+ WHERE q.retention_enabled = true
148
+ ```
149
+
150
+ ### 2.4 Client Library Changes
151
+
152
+ #### `src/client/queenClient.js`
153
+ Update configure method signature:
154
+ ```javascript
155
+ const configure = async (options = {}) => {
156
+ const { queue, namespace, task, options: configOptions = {} } = options;
157
+ // Remove partition parameter handling
158
+ return withRetry(
159
+ () => http.post('/api/v1/configure', {
160
+ queue,
161
+ namespace,
162
+ task,
163
+ options: configOptions
164
+ }),
165
+ retryAttempts,
166
+ retryDelay
167
+ );
168
+ };
169
+ ```
170
+
171
+ ### 2.5 Cache Changes
172
+
173
+ #### `src/managers/resourceCache.js`
174
+ Remove partition options from cache structure:
175
+ ```javascript
176
+ // Before:
177
+ resources.set(cacheKey, {
178
+ queueId,
179
+ queueName,
180
+ partitionId,
181
+ partitionOptions, // Remove this
182
+ encryptionEnabled,
183
+ maxWaitTimeSeconds
184
+ });
185
+
186
+ // After:
187
+ resources.set(cacheKey, {
188
+ queueId,
189
+ queueName,
190
+ partitionId,
191
+ // All queue config fetched when needed
192
+ });
193
+ ```
194
+
195
+ ---
196
+
197
+ ## 3. Migration Strategy
198
+
199
+ ### 3.1 Migration Script: `migrations/002-queue-only-config.sql`
200
+
201
+ ```sql
202
+ -- Step 1: Add new columns to queues table
203
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS lease_time INTEGER;
204
+ ALTER TABLE queen.queues ADD COLUMN IF NOT EXISTS retry_limit INTEGER;
205
+ -- ... (all other columns)
206
+
207
+ -- Step 2: Migrate existing partition options to queue level
208
+ -- For queues with single partition or all partitions having same config
209
+ UPDATE queen.queues q
210
+ SET
211
+ lease_time = COALESCE((p.options->>'leaseTime')::int, 300),
212
+ retry_limit = COALESCE((p.options->>'retryLimit')::int, 3),
213
+ retry_delay = COALESCE((p.options->>'retryDelay')::int, 1000),
214
+ max_size = COALESCE((p.options->>'maxSize')::int, 10000),
215
+ ttl = COALESCE((p.options->>'ttl')::int, 3600),
216
+ dead_letter_queue = COALESCE((p.options->>'deadLetterQueue')::boolean, false),
217
+ dlq_after_max_retries = COALESCE((p.options->>'dlqAfterMaxRetries')::boolean, false),
218
+ delayed_processing = COALESCE((p.options->>'delayedProcessing')::int, 0),
219
+ window_buffer = COALESCE((p.options->>'windowBuffer')::int, 0),
220
+ retention_seconds = COALESCE((p.options->>'retentionSeconds')::int, 0),
221
+ completed_retention_seconds = COALESCE((p.options->>'completedRetentionSeconds')::int, 0),
222
+ retention_enabled = COALESCE((p.options->>'retentionEnabled')::boolean, false)
223
+ FROM (
224
+ SELECT DISTINCT ON (queue_id)
225
+ queue_id,
226
+ options
227
+ FROM queen.partitions
228
+ WHERE name = 'Default' OR queue_id IN (
229
+ SELECT queue_id FROM queen.partitions GROUP BY queue_id HAVING COUNT(*) = 1
230
+ )
231
+ ORDER BY queue_id, name = 'Default' DESC
232
+ ) p
233
+ WHERE q.id = p.queue_id;
234
+
235
+ -- Step 3: Set defaults for any remaining nulls
236
+ UPDATE queen.queues
237
+ SET
238
+ lease_time = COALESCE(lease_time, 300),
239
+ retry_limit = COALESCE(retry_limit, 3),
240
+ retry_delay = COALESCE(retry_delay, 1000),
241
+ max_size = COALESCE(max_size, 10000),
242
+ ttl = COALESCE(ttl, 3600),
243
+ dead_letter_queue = COALESCE(dead_letter_queue, false),
244
+ dlq_after_max_retries = COALESCE(dlq_after_max_retries, false),
245
+ delayed_processing = COALESCE(delayed_processing, 0),
246
+ window_buffer = COALESCE(window_buffer, 0),
247
+ retention_seconds = COALESCE(retention_seconds, 0),
248
+ completed_retention_seconds = COALESCE(completed_retention_seconds, 0),
249
+ retention_enabled = COALESCE(retention_enabled, false);
250
+
251
+ -- Step 4: Drop partition columns
252
+ ALTER TABLE queen.partitions
253
+ DROP COLUMN IF EXISTS options,
254
+ DROP COLUMN IF EXISTS priority;
255
+
256
+ -- Step 5: Log migration for queues with conflicting partition configs
257
+ CREATE TABLE IF NOT EXISTS queen.migration_log (
258
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
259
+ queue_name VARCHAR(255),
260
+ message TEXT,
261
+ created_at TIMESTAMP DEFAULT NOW()
262
+ );
263
+
264
+ INSERT INTO queen.migration_log (queue_name, message)
265
+ SELECT q.name,
266
+ 'Queue had multiple partitions with different configurations. Used Default partition or first partition settings.'
267
+ FROM queen.queues q
268
+ WHERE q.id IN (
269
+ SELECT queue_id
270
+ FROM queen.partitions
271
+ GROUP BY queue_id
272
+ HAVING COUNT(DISTINCT options::text) > 1
273
+ );
274
+ ```
275
+
276
+ ---
277
+
278
+ ## 4. Test Updates Required
279
+
280
+ ### Files to Update:
281
+ 1. `src/test/test.js` - Update all configuration tests
282
+ 2. `src/test/comprehensive-test.js` - Update configuration tests
283
+ 3. `src/test/core-features-test.js` - Update configuration tests
284
+ 4. `examples/continuous-producer.js` - Remove partition from configure
285
+ 5. `examples/continuous-consumer.js` - Update configuration
286
+ 6. All other example files using configure
287
+
288
+ ### Test Changes Example:
289
+ ```javascript
290
+ // Before:
291
+ await client.configure({
292
+ queue: 'test-queue',
293
+ partition: 'test-partition',
294
+ options: { leaseTime: 600, retryLimit: 5 }
295
+ });
296
+
297
+ // After:
298
+ await client.configure({
299
+ queue: 'test-queue',
300
+ options: { leaseTime: 600, retryLimit: 5 }
301
+ });
302
+ ```
303
+
304
+ ---
305
+
306
+ ## 5. API Changes
307
+
308
+ ### Configuration Endpoint
309
+
310
+ **Before:**
311
+ ```javascript
312
+ POST /api/v1/configure
313
+ {
314
+ "queue": "myqueue",
315
+ "partition": "mypartition", // Optional
316
+ "namespace": "...", // Optional
317
+ "task": "...", // Optional
318
+ "options": {
319
+ "leaseTime": 300,
320
+ "retryLimit": 3,
321
+ // etc.
322
+ }
323
+ }
324
+ ```
325
+
326
+ **After:**
327
+ ```javascript
328
+ POST /api/v1/configure
329
+ {
330
+ "queue": "myqueue",
331
+ "namespace": "...", // Optional
332
+ "task": "...", // Optional
333
+ "options": {
334
+ "leaseTime": 300,
335
+ "retryLimit": 3,
336
+ // etc.
337
+ }
338
+ }
339
+ // Note: partition parameter is removed/ignored
340
+ ```
341
+
342
+ ---
343
+
344
+ ## 6. Implementation Phases
345
+
346
+ ### Phase 1: Database Migration (Day 1)
347
+ - [ ] Create migration script `002-queue-only-config.sql`
348
+ - [ ] Test migration on development database
349
+ - [ ] Create rollback script
350
+
351
+ ### Phase 2: Core Code Changes (Day 2-3)
352
+ - [ ] Update `queueManagerOptimized.js`
353
+ - [ ] Update `resourceCache.js`
354
+ - [ ] Fix hardcoded lease time bug
355
+
356
+ ### Phase 3: Route Updates (Day 3)
357
+ - [ ] Update `configure.js`
358
+ - [ ] Update `resources.js`
359
+ - [ ] Update `messages.js`
360
+
361
+ ### Phase 4: Service Updates (Day 4)
362
+ - [ ] Update `retentionService.js`
363
+ - [ ] Verify `evictionService.js` (no changes needed)
364
+
365
+ ### Phase 5: Client & Tests (Day 4-5)
366
+ - [ ] Update `queenClient.js`
367
+ - [ ] Update all test files
368
+ - [ ] Update example files
369
+
370
+ ### Phase 6: Documentation (Day 5)
371
+ - [ ] Update API.md
372
+ - [ ] Update README.md
373
+ - [ ] Create migration guide
374
+
375
+ ---
376
+
377
+ ## 7. Rollback Plan
378
+
379
+ If issues arise, rollback strategy:
380
+
381
+ 1. **Database Rollback:**
382
+ ```sql
383
+ -- Re-add partition columns
384
+ ALTER TABLE queen.partitions
385
+ ADD COLUMN IF NOT EXISTS options JSONB DEFAULT '{"leaseTime": 300, "retryLimit": 3}',
386
+ ADD COLUMN IF NOT EXISTS priority INTEGER DEFAULT 0;
387
+
388
+ -- Restore partition options from queue settings
389
+ UPDATE queen.partitions p
390
+ SET options = json_build_object(
391
+ 'leaseTime', q.lease_time,
392
+ 'retryLimit', q.retry_limit,
393
+ -- ... other fields
394
+ )
395
+ FROM queen.queues q
396
+ WHERE p.queue_id = q.id;
397
+
398
+ -- Remove queue columns
399
+ ALTER TABLE queen.queues
400
+ DROP COLUMN IF EXISTS lease_time,
401
+ DROP COLUMN IF EXISTS retry_limit;
402
+ -- ... etc
403
+ ```
404
+
405
+ 2. **Code Rollback:**
406
+ - Revert git commits
407
+ - Restore previous deployment
408
+
409
+ ---
410
+
411
+ ## 8. Benefits After Implementation
412
+
413
+ 1. **Simpler Mental Model**: Queue = configuration, Partition = FIFO container
414
+ 2. **Cleaner API**: No confusion about where to set options
415
+ 3. **Bug Fixes**: Actually use configured leaseTime instead of hardcoded value
416
+ 4. **Reduced Complexity**: Less code, easier maintenance
417
+ 5. **Better Performance**: Fewer joins, simpler queries
418
+ 6. **Consistent Behavior**: All partitions in a queue behave the same way
419
+
420
+ ---
421
+
422
+ ## 9. Risks and Mitigations
423
+
424
+ ### Risk 1: Data Loss During Migration
425
+ **Mitigation**: Full backup before migration, test on staging first
426
+
427
+ ### Risk 2: Breaking Existing Clients
428
+ **Mitigation**: Temporarily accept but ignore partition parameter, deprecation period
429
+
430
+ ### Risk 3: Performance Impact
431
+ **Mitigation**: Add proper indexes on new queue columns
432
+
433
+ ### Risk 4: Different Partition Behaviors Lost
434
+ **Mitigation**: Document in migration log, provide manual override if needed
435
+
436
+ ---
437
+
438
+ ## 10. Success Criteria
439
+
440
+ - [ ] All tests pass with new configuration
441
+ - [ ] No hardcoded values in code
442
+ - [ ] API is backward compatible (ignores partition parameter)
443
+ - [ ] Migration completes without data loss
444
+ - [ ] Performance metrics remain stable or improve
445
+ - [ ] Documentation is updated
446
+
447
+ ---
448
+
449
+ ## Notes
450
+
451
+ - This is a breaking change for the internal architecture but can be made backward compatible at the API level
452
+ - The partition parameter in configure can be accepted but ignored for a transition period
453
+ - Consider adding a feature flag to enable/disable new behavior during rollout