queen-mq 0.1.0 → 0.1.2
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/API.md +862 -752
- package/AUTH.md +2044 -0
- package/LICENSE.md +202 -0
- package/README.md +1705 -1051
- package/WEBAPP.md +1889 -0
- package/assets/dashboard-01.png +0 -0
- package/assets/queen-logo-blue.svg +210 -0
- package/assets/queen-logo-cyan.svg +210 -0
- package/assets/queen-logo-indigo.svg +210 -0
- package/assets/queen-logo-orange.svg +210 -0
- package/assets/queen-logo-pink.svg +210 -0
- package/assets/queen-logo-purple.svg +210 -0
- package/assets/queen-logo-rose.svg +239 -0
- package/assets/queen-logo.svg +263 -0
- package/examples/batch-processing.js +58 -0
- package/examples/test-complete-client.js +260 -0
- package/examples/test-dashboard-api.js +200 -0
- package/examples/test-traceid.js +147 -0
- package/package.json +17 -4
- package/server.log +1 -0
- package/src/benchmark/consumer.js +207 -0
- package/src/benchmark/consumer_multi.js +216 -0
- package/src/benchmark/producer.js +75 -0
- package/src/benchmark/producer_multi.js +115 -0
- package/src/client/client.js +300 -31
- package/src/client/queenClient.js +5 -0
- package/src/cluster-server.js +242 -0
- package/src/config.js +19 -5
- package/src/database/connection.js +42 -16
- package/src/database/poolManager.js +7 -0
- package/src/database/schema-v2.sql +194 -130
- package/src/managers/queueManagerOptimized.js +823 -933
- package/src/managers/systemEventManager.js +8 -3
- package/src/routes/messages.js +127 -57
- package/src/routes/pop.js +27 -43
- package/src/routes/resources.js +61 -27
- package/src/routes/status.js +1037 -0
- package/src/server.js +308 -272
- package/src/services/evictionService.js +57 -28
- package/src/services/retentionService.js +44 -11
- package/src/test/MIGRATION_ISSUES.md +174 -0
- package/src/test/README.md +203 -0
- package/src/test/advanced-pattern-tests.js +1137 -0
- package/src/test/bus-mode-tests.js +361 -0
- package/src/test/core-tests.js +342 -0
- package/src/test/edge-case-tests.js +561 -0
- package/src/test/enterprise-tests.js +637 -0
- package/src/test/partition-locking-tests.js +545 -0
- package/src/test/test-new.js +278 -0
- package/src/test/test.js +6 -3
- package/src/test/utils.js +169 -0
- package/src/utils/streaming.js +231 -0
- package/src/utils/uuid.js +2 -2
- package/src/websocket/wsServer.js +10 -3
- package/test-keepalive-v2.sh +22 -0
- package/webapp/COLOR_GUIDE.md +118 -0
- package/webapp/README.md +143 -0
- package/webapp/index.html +14 -0
- package/webapp/package-lock.json +3184 -0
- package/webapp/package.json +25 -0
- package/webapp/postcss.config.js +7 -0
- package/webapp/public/assets/queen-logo-blue.svg +210 -0
- package/webapp/public/assets/queen-logo-cyan.svg +210 -0
- package/webapp/public/assets/queen-logo-indigo.svg +210 -0
- package/webapp/public/assets/queen-logo-orange.svg +210 -0
- package/webapp/public/assets/queen-logo-pink.svg +210 -0
- package/webapp/public/assets/queen-logo-purple.svg +210 -0
- package/webapp/public/assets/queen-logo-rose.svg +239 -0
- package/webapp/public/assets/queen-logo.svg +263 -0
- package/webapp/src/App.vue +19 -0
- package/webapp/src/api/analytics.js +10 -0
- package/webapp/src/api/client.js +29 -0
- package/webapp/src/api/consumers.js +52 -0
- package/webapp/src/api/health.js +7 -0
- package/webapp/src/api/messages.js +26 -0
- package/webapp/src/api/queues.js +14 -0
- package/webapp/src/api/resources.js +8 -0
- package/webapp/src/assets/styles/main.css +357 -0
- package/webapp/src/components/analytics/AnalyticsFilters.vue +87 -0
- package/webapp/src/components/analytics/AnalyticsMetrics.vue +57 -0
- package/webapp/src/components/analytics/MessageDistributionChart.vue +111 -0
- package/webapp/src/components/analytics/MessageFlowChart.vue +173 -0
- package/webapp/src/components/analytics/TimeRangeSelector.vue +27 -0
- package/webapp/src/components/analytics/TopQueuesChart.vue +132 -0
- package/webapp/src/components/common/ConfirmDialog.vue +56 -0
- package/webapp/src/components/common/LoadingSpinner.vue +6 -0
- package/webapp/src/components/common/MetricCard.vue +43 -0
- package/webapp/src/components/common/StatusBadge.vue +45 -0
- package/webapp/src/components/dashboard/MessageStatusCard.vue +50 -0
- package/webapp/src/components/dashboard/PerformanceCard.vue +38 -0
- package/webapp/src/components/dashboard/ThroughputChart.vue +182 -0
- package/webapp/src/components/dashboard/TopQueuesTable.vue +53 -0
- package/webapp/src/components/layout/AppLayout.vue +110 -0
- package/webapp/src/components/layout/AppSidebar.vue +304 -0
- package/webapp/src/components/messages/MessageDetailPanel.vue +242 -0
- package/webapp/src/components/messages/MessageFilters.vue +114 -0
- package/webapp/src/components/queue-detail/PartitionList.vue +79 -0
- package/webapp/src/components/queue-detail/PushMessageModal.vue +175 -0
- package/webapp/src/components/queue-detail/QueueConfig.vue +63 -0
- package/webapp/src/components/queue-detail/QueueDetailHeader.vue +53 -0
- package/webapp/src/components/queue-detail/RecentMessages.vue +76 -0
- package/webapp/src/components/queues/CreateQueueModal.vue +193 -0
- package/webapp/src/components/queues/QueueFilters.vue +90 -0
- package/webapp/src/composables/useApi.js +34 -0
- package/webapp/src/composables/useTheme.js +36 -0
- package/webapp/src/main.js +11 -0
- package/webapp/src/router/index.js +42 -0
- package/webapp/src/utils/colors.js +96 -0
- package/webapp/src/utils/formatters.js +49 -0
- package/webapp/src/views/Analytics.vue +377 -0
- package/webapp/src/views/ConsumerGroups.vue +433 -0
- package/webapp/src/views/Dashboard.vue +418 -0
- package/webapp/src/views/Messages.vue +361 -0
- package/webapp/src/views/QueueDetail.vue +582 -0
- package/webapp/src/views/Queues.vue +496 -0
- package/webapp/tailwind.config.js +25 -0
- package/webapp/vite.config.js +10 -0
- package/CACHE.md +0 -519
- package/DASHBOARD-V3.md +0 -478
- package/DASHBOARD.md +0 -382
- package/MOD_QUEUE.md +0 -453
- package/PARTITION_LOCKING_DESIGN.md +0 -989
- package/PLAN.md +0 -707
- package/QUERY_ANALSYS.md +0 -72
- package/QUEUE_BUS.md +0 -334
- package/V2-PLAN.md +0 -236
- package/dashboard/.vscode/extensions.json +0 -3
- package/dashboard/README.md +0 -5
- package/dashboard/index.html +0 -14
- package/dashboard/package-lock.json +0 -1458
- package/dashboard/package.json +0 -25
- package/dashboard/public/vite.svg +0 -1
- package/dashboard/src/App.vue +0 -29
- package/dashboard/src/assets/styles/main.css +0 -908
- package/dashboard/src/assets/vue.svg +0 -1
- package/dashboard/src/components/cards/MetricCard.vue +0 -298
- package/dashboard/src/components/charts/QueueDepthChart.vue +0 -276
- package/dashboard/src/components/charts/QueueLagChart.vue +0 -436
- package/dashboard/src/components/charts/ThroughputChart.vue +0 -302
- package/dashboard/src/components/common/ActivityFeed.vue +0 -251
- package/dashboard/src/components/layout/AppHeader.vue +0 -208
- package/dashboard/src/components/layout/AppLayout.vue +0 -88
- package/dashboard/src/components/layout/AppSidebar.vue +0 -261
- package/dashboard/src/main.js +0 -44
- package/dashboard/src/router.js +0 -54
- package/dashboard/src/services/api.js +0 -187
- package/dashboard/src/services/websocket.js +0 -167
- package/dashboard/src/utils/constants.js +0 -56
- package/dashboard/src/utils/helpers.js +0 -118
- package/dashboard/src/views/Analytics.vue +0 -912
- package/dashboard/src/views/Dashboard.vue +0 -906
- package/dashboard/src/views/Messages.vue +0 -437
- package/dashboard/src/views/QueueDetail.vue +0 -501
- package/dashboard/src/views/Queues.vue +0 -333
- package/dashboard/vite.config.js +0 -30
- package/debug-namespace.js +0 -110
- package/docs/long-polling.md +0 -159
- package/docs/multi-server-cache-solutions.md +0 -185
- package/docs/performance-tuning.md +0 -222
- package/src/routes/analytics.js +0 -812
package/QUERY_ANALSYS.md
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
### Query Analysis and Improvement Plan
|
|
2
|
-
|
|
3
|
-
This document outlines the planned changes to improve SQL safety, correctness, FIFO guarantees, duplicate-avoidance, and performance.
|
|
4
|
-
|
|
5
|
-
## Goals
|
|
6
|
-
- Enforce per-partition FIFO even when no partition is specified.
|
|
7
|
-
- Prevent duplicate message selection across workers.
|
|
8
|
-
- Harden transactions against injection and long blocks.
|
|
9
|
-
- Reduce planner anti-patterns; improve query efficiency.
|
|
10
|
-
- Align retention/eviction with schema v2 semantics.
|
|
11
|
-
|
|
12
|
-
## Changes and Why
|
|
13
|
-
|
|
14
|
-
1) Security and transaction hardening
|
|
15
|
-
- What: Whitelist transaction isolation levels in `withTransaction` (no dynamic interpolation).
|
|
16
|
-
- Why: Avoids SQL injection risk and invalid isolation values.
|
|
17
|
-
|
|
18
|
-
- What: Set `statement_timeout` and `lock_timeout` via `SET LOCAL` at transaction start.
|
|
19
|
-
- Why: Prevents long blocking operations and stuck workers under contention.
|
|
20
|
-
|
|
21
|
-
- What: Add retry for serialization failures (SQLSTATE 40001) and deadlocks (40P01) in the query wrapper.
|
|
22
|
-
- Why: These are expected under high contention; bounded retry improves resiliency.
|
|
23
|
-
|
|
24
|
-
2) Strict FIFO when partition is unspecified
|
|
25
|
-
- What: Partition-first selection in queue-mode and namespace/task pop paths; lock the chosen partition, then fetch only from that partition ordered by `created_at ASC`.
|
|
26
|
-
- Why: Guarantees FIFO per partition and eliminates mixed-partition batches.
|
|
27
|
-
|
|
28
|
-
- What: Add fairness heuristic for choosing the partition (e.g., partition with the oldest pending message or least recent `last_activity`).
|
|
29
|
-
- Why: Prevents starvation and balances throughput without breaking FIFO.
|
|
30
|
-
|
|
31
|
-
3) Availability predicate simplification
|
|
32
|
-
- What: Replace `LEFT JOIN messages_status ... WHERE (ms.id IS NULL OR ms.status IN (...))` with `NOT EXISTS`/UNION.
|
|
33
|
-
- Why: Removes OR conditions that block index use; produces better plans.
|
|
34
|
-
|
|
35
|
-
- What: Precompute per-queue time thresholds (delayed_processing, max_wait_time, window_buffer) in a small CTE.
|
|
36
|
-
- Why: Avoids non-sargable predicates involving NOW() and enables index range scans on `created_at`.
|
|
37
|
-
|
|
38
|
-
4) Pop query shaping
|
|
39
|
-
- What: Eliminate correlated subselects in `RETURNING` by projecting needed columns in the CTE and returning them directly.
|
|
40
|
-
- Why: Avoids per-row subqueries; simpler and faster.
|
|
41
|
-
|
|
42
|
-
- What: Keep `FOR UPDATE OF m SKIP LOCKED` in queue-mode pops.
|
|
43
|
-
- Why: Ensures a message is only claimed by one worker in competing consumer mode.
|
|
44
|
-
|
|
45
|
-
5) Bus-mode (consumer groups)
|
|
46
|
-
- What: Use `ON CONFLICT DO NOTHING` (or update) when inserting into `messages_status`.
|
|
47
|
-
- Why: Handles races on `(message_id, consumer_group)` without surfacing errors; maintains single-delivery per group.
|
|
48
|
-
|
|
49
|
-
6) API pagination
|
|
50
|
-
- What: Implement keyset (cursor) pagination for `listMessages` while preserving offset for backward compatibility.
|
|
51
|
-
- Why: OFFSET is O(n) at high pages; keyset keeps scans bounded and stable using `(created_at, id)`.
|
|
52
|
-
|
|
53
|
-
7) Retention and eviction
|
|
54
|
-
- What: Align `retentionService` with schema v2: delete only when configured to do so; rely on cascade for statuses.
|
|
55
|
-
- Why: Prevents unintended loss of unprocessed messages; keeps behavior explicit.
|
|
56
|
-
|
|
57
|
-
- What: Keep eviction as status transitions (e.g., `evicted`) and log counts to retention history.
|
|
58
|
-
- Why: Avoids destructive deletes while signaling expired messages.
|
|
59
|
-
|
|
60
|
-
8) Tests
|
|
61
|
-
- What: Add/adjust tests for single-partition FIFO (when partition unspecified), no duplicates under concurrency (queue/bus), keyset pagination, and retention/eviction behavior.
|
|
62
|
-
- Why: Prevent regressions and validate concurrency semantics.
|
|
63
|
-
|
|
64
|
-
## Rollout Order
|
|
65
|
-
1. Transaction hardening (whitelist isolation, timeouts) and retry policy.
|
|
66
|
-
2. Partition-first pop logic (queue-mode, namespace/task) with fairness.
|
|
67
|
-
3. Availability predicate rewrite and time-threshold precompute.
|
|
68
|
-
4. Pop `RETURNING` cleanup (remove correlated subselects).
|
|
69
|
-
5. Bus-mode conflict handling with ON CONFLICT.
|
|
70
|
-
6. Keyset pagination for `listMessages`.
|
|
71
|
-
7. Retention adjustments.
|
|
72
|
-
8. Tests and docs.
|
package/QUEUE_BUS.md
DELETED
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
# Queue/Bus Mode Implementation Plan
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
Implement dynamic queue/bus mode based on consumer group parameter, allowing the same queue to serve both competing consumers (queue mode) and broadcast to multiple consumer groups (bus mode).
|
|
5
|
-
|
|
6
|
-
## Core Concept
|
|
7
|
-
- **Queue Mode**: No `consumerGroup` specified → competing consumers (traditional queue behavior)
|
|
8
|
-
- **Bus Mode**: `consumerGroup` specified → each consumer group gets all messages (pub/sub behavior)
|
|
9
|
-
- **Mixed Mode**: Same queue can serve both patterns simultaneously
|
|
10
|
-
|
|
11
|
-
## Architecture Changes
|
|
12
|
-
|
|
13
|
-
### 1. Database Schema Changes (`src/database/schema-v2.sql`)
|
|
14
|
-
|
|
15
|
-
#### 1.1 Modify Messages Table
|
|
16
|
-
- Remove all status-related fields from `queen.messages`
|
|
17
|
-
- Keep only: `id`, `transaction_id`, `partition_id`, `payload`, `created_at`, `is_encrypted`
|
|
18
|
-
- Keep `transaction_id` in messages table (set during push, immutable)
|
|
19
|
-
|
|
20
|
-
#### 1.2 Create Messages Status Table
|
|
21
|
-
```sql
|
|
22
|
-
CREATE TABLE queen.messages_status (
|
|
23
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
24
|
-
message_id UUID REFERENCES queen.messages(id) ON DELETE CASCADE,
|
|
25
|
-
consumer_group VARCHAR(255), -- NULL for queue mode
|
|
26
|
-
status VARCHAR(20) DEFAULT 'pending',
|
|
27
|
-
worker_id VARCHAR(255),
|
|
28
|
-
locked_at TIMESTAMP,
|
|
29
|
-
completed_at TIMESTAMP,
|
|
30
|
-
failed_at TIMESTAMP,
|
|
31
|
-
error_message TEXT,
|
|
32
|
-
retry_count INTEGER DEFAULT 0,
|
|
33
|
-
lease_expires_at TIMESTAMP,
|
|
34
|
-
processing_at TIMESTAMP,
|
|
35
|
-
created_at TIMESTAMP DEFAULT NOW(),
|
|
36
|
-
UNIQUE(message_id, consumer_group)
|
|
37
|
-
);
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
#### 1.3 Consumer Group Registry (Optional)
|
|
41
|
-
```sql
|
|
42
|
-
CREATE TABLE queen.consumer_groups (
|
|
43
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
44
|
-
queue_id UUID REFERENCES queen.queues(id) ON DELETE CASCADE,
|
|
45
|
-
name VARCHAR(255) NOT NULL,
|
|
46
|
-
created_at TIMESTAMP DEFAULT NOW(),
|
|
47
|
-
subscription_start_from TIMESTAMP, -- NULL = consume all, timestamp = consume from this point
|
|
48
|
-
active BOOLEAN DEFAULT true,
|
|
49
|
-
UNIQUE(queue_id, name)
|
|
50
|
-
);
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
#### 1.3 Create Optimized Indexes
|
|
54
|
-
- Index for queue mode lookups (consumer_group IS NULL)
|
|
55
|
-
- Index for bus mode lookups (consumer_group IS NOT NULL)
|
|
56
|
-
- Composite indexes for efficient pop operations
|
|
57
|
-
- Indexes for lease expiration checks
|
|
58
|
-
|
|
59
|
-
### 2. Consumer Group Subscription Strategies
|
|
60
|
-
|
|
61
|
-
#### Option 1: Consume All Messages (Default)
|
|
62
|
-
- New consumer groups start from the beginning
|
|
63
|
-
- Process all existing messages in the queue
|
|
64
|
-
- Good for: Analytics, audit logs, data replication
|
|
65
|
-
|
|
66
|
-
#### Option 2: Consume From Subscription Time
|
|
67
|
-
- New consumer groups only see messages created after subscription
|
|
68
|
-
- Skip all historical messages
|
|
69
|
-
- Good for: Real-time notifications, monitoring
|
|
70
|
-
|
|
71
|
-
#### Option 3: Consume From Specific Time
|
|
72
|
-
- Consumer group specifies a start timestamp
|
|
73
|
-
- Process messages from that point forward
|
|
74
|
-
- Good for: Replay scenarios, recovery
|
|
75
|
-
|
|
76
|
-
#### Implementation Approach:
|
|
77
|
-
```javascript
|
|
78
|
-
// Option 1: Consume all (default)
|
|
79
|
-
client.pop({
|
|
80
|
-
queue: 'events',
|
|
81
|
-
consumerGroup: 'analytics'
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
// Option 2: From subscription time
|
|
85
|
-
client.pop({
|
|
86
|
-
queue: 'events',
|
|
87
|
-
consumerGroup: 'notifications',
|
|
88
|
-
subscriptionMode: 'new' // Only new messages
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// Option 3: From specific time
|
|
92
|
-
client.pop({
|
|
93
|
-
queue: 'events',
|
|
94
|
-
consumerGroup: 'replay',
|
|
95
|
-
subscriptionFrom: '2024-01-01T00:00:00Z'
|
|
96
|
-
});
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
#### Database Implementation:
|
|
100
|
-
```sql
|
|
101
|
-
-- When popping with a new consumer group:
|
|
102
|
-
-- 1. Check if consumer group exists in registry
|
|
103
|
-
-- 2. If not, create it with subscription preferences
|
|
104
|
-
-- 3. Only return messages based on subscription_start_from
|
|
105
|
-
|
|
106
|
-
-- For "new only" mode:
|
|
107
|
-
INSERT INTO queen.consumer_groups (queue_id, name, subscription_start_from)
|
|
108
|
-
VALUES ($1, $2, NOW());
|
|
109
|
-
|
|
110
|
-
-- For "all messages" mode:
|
|
111
|
-
INSERT INTO queen.consumer_groups (queue_id, name, subscription_start_from)
|
|
112
|
-
VALUES ($1, $2, NULL); -- NULL means consume all
|
|
113
|
-
|
|
114
|
-
-- Pop query considers subscription time:
|
|
115
|
-
SELECT m.* FROM queen.messages m
|
|
116
|
-
WHERE m.partition_id = $1
|
|
117
|
-
AND NOT EXISTS (
|
|
118
|
-
SELECT 1 FROM queen.messages_status ms
|
|
119
|
-
WHERE ms.message_id = m.id
|
|
120
|
-
AND ms.consumer_group = $2
|
|
121
|
-
)
|
|
122
|
-
AND m.created_at >= COALESCE(
|
|
123
|
-
(SELECT subscription_start_from
|
|
124
|
-
FROM queen.consumer_groups
|
|
125
|
-
WHERE queue_id = $3 AND name = $2),
|
|
126
|
-
'1970-01-01'::timestamp -- If NULL, consume all
|
|
127
|
-
)
|
|
128
|
-
ORDER BY m.created_at ASC
|
|
129
|
-
LIMIT $4;
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
### 3. Backend Changes
|
|
133
|
-
|
|
134
|
-
#### 3.1 Queue Manager (`src/managers/queueManagerOptimized.js`)
|
|
135
|
-
|
|
136
|
-
##### Push Messages
|
|
137
|
-
- Keep existing behavior: generate transaction_id during push
|
|
138
|
-
- Only insert into messages table (no status entry)
|
|
139
|
-
- Transaction_id remains in messages table (immutable)
|
|
140
|
-
|
|
141
|
-
##### Pop Messages
|
|
142
|
-
- **Queue Mode Logic** (no consumer group):
|
|
143
|
-
```javascript
|
|
144
|
-
// 1. Find messages without status OR with pending status where consumer_group IS NULL
|
|
145
|
-
// 2. Create/update status entry with consumer_group = NULL
|
|
146
|
-
// 3. Mark as processing with lease
|
|
147
|
-
// 4. Return messages
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
- **Bus Mode Logic** (with consumer group):
|
|
151
|
-
```javascript
|
|
152
|
-
// 1. Find messages without status entry for this specific consumer_group
|
|
153
|
-
// 2. Create status entry for this consumer_group
|
|
154
|
-
// 3. Mark as processing with lease
|
|
155
|
-
// 4. Return messages
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
##### Acknowledge Messages
|
|
159
|
-
- Update status for specific consumer_group (or NULL)
|
|
160
|
-
- In bus mode, message stays available for other consumer groups
|
|
161
|
-
- In queue mode, message is done after single acknowledgment
|
|
162
|
-
|
|
163
|
-
##### Reclaim Leases
|
|
164
|
-
- Check lease expiration per consumer_group
|
|
165
|
-
- Reset to pending for that specific consumer_group only
|
|
166
|
-
|
|
167
|
-
#### 3.2 Pop Route (`src/routes/pop.js`)
|
|
168
|
-
- Accept optional `consumerGroup` parameter
|
|
169
|
-
- Pass through to queue manager
|
|
170
|
-
|
|
171
|
-
#### 3.3 Server Routes (`src/server.js`)
|
|
172
|
-
- Update pop endpoint to accept consumer_group query parameter
|
|
173
|
-
- Ensure backward compatibility (no consumer_group = queue mode)
|
|
174
|
-
|
|
175
|
-
### 4. Client SDK Changes (`src/client/queenClient.js`)
|
|
176
|
-
|
|
177
|
-
#### 4.1 Pop Method
|
|
178
|
-
```javascript
|
|
179
|
-
pop({ queue, partition, consumerGroup, wait, timeout, batch })
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
#### 4.2 Consume Method
|
|
183
|
-
```javascript
|
|
184
|
-
consume({ queue, partition, consumerGroup, handler, options })
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
#### 4.3 Documentation
|
|
188
|
-
- Add consumer group examples
|
|
189
|
-
- Document queue vs bus mode behavior
|
|
190
|
-
|
|
191
|
-
### 5. Testing (`src/test/test.js`)
|
|
192
|
-
|
|
193
|
-
#### 5.1 Queue Mode Tests
|
|
194
|
-
- Test competing consumers (no consumer group)
|
|
195
|
-
- Verify only one consumer gets each message
|
|
196
|
-
- Test acknowledgment completes message
|
|
197
|
-
|
|
198
|
-
#### 5.2 Bus Mode Tests
|
|
199
|
-
- Test multiple consumer groups
|
|
200
|
-
- Verify all groups get all messages
|
|
201
|
-
- Test independent acknowledgment per group
|
|
202
|
-
- Test consumer group isolation
|
|
203
|
-
|
|
204
|
-
#### 5.3 Mixed Mode Tests
|
|
205
|
-
- Test same queue with both modes simultaneously
|
|
206
|
-
- Verify queue mode consumers compete
|
|
207
|
-
- Verify bus mode consumers all receive messages
|
|
208
|
-
|
|
209
|
-
#### 5.4 Edge Cases
|
|
210
|
-
- Test consumer group with special characters
|
|
211
|
-
- Test very long consumer group names
|
|
212
|
-
- Test lease expiration per consumer group
|
|
213
|
-
- Test retry logic per consumer group
|
|
214
|
-
|
|
215
|
-
### 6. Examples
|
|
216
|
-
|
|
217
|
-
#### 6.1 Create Bus Mode Example (`examples/bus-mode.js`)
|
|
218
|
-
- Demonstrate multiple consumer groups
|
|
219
|
-
- Show independent progress tracking
|
|
220
|
-
- Compare with queue mode
|
|
221
|
-
|
|
222
|
-
#### 6.2 Create Mixed Mode Example (`examples/mixed-mode.js`)
|
|
223
|
-
- Same queue, different consumption patterns
|
|
224
|
-
- Workers + Analytics + Notifications
|
|
225
|
-
|
|
226
|
-
### 7. Documentation Updates
|
|
227
|
-
|
|
228
|
-
#### 7.1 README.md
|
|
229
|
-
- Add Bus Mode section
|
|
230
|
-
- Document consumer groups
|
|
231
|
-
- Add comparison with Kafka
|
|
232
|
-
- Update API reference
|
|
233
|
-
|
|
234
|
-
#### 7.2 API.md
|
|
235
|
-
- Document consumer_group parameter
|
|
236
|
-
- Add bus mode examples
|
|
237
|
-
|
|
238
|
-
## Implementation Steps
|
|
239
|
-
|
|
240
|
-
### Phase 1: Database Schema
|
|
241
|
-
1. Backup existing schema
|
|
242
|
-
2. Modify `schema-v2.sql` with new structure
|
|
243
|
-
3. Drop and recreate database:
|
|
244
|
-
```bash
|
|
245
|
-
nvm use 22 && node init-db.js
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
### Phase 2: Backend Core
|
|
249
|
-
1. Update queue manager push logic
|
|
250
|
-
2. Implement dual-mode pop logic
|
|
251
|
-
3. Update acknowledgment logic
|
|
252
|
-
4. Update lease reclaim logic
|
|
253
|
-
5. Test with basic operations
|
|
254
|
-
|
|
255
|
-
### Phase 3: API Layer
|
|
256
|
-
1. Update pop route to accept consumer_group
|
|
257
|
-
2. Update server endpoints
|
|
258
|
-
3. Ensure backward compatibility
|
|
259
|
-
4. Test API endpoints
|
|
260
|
-
|
|
261
|
-
### Phase 4: Client SDK
|
|
262
|
-
1. Add consumerGroup parameter to pop
|
|
263
|
-
2. Update consume method
|
|
264
|
-
3. Add TypeScript types (if applicable)
|
|
265
|
-
4. Test client operations
|
|
266
|
-
|
|
267
|
-
### Phase 5: Testing
|
|
268
|
-
1. Write comprehensive test suite
|
|
269
|
-
2. Test queue mode (backward compatibility)
|
|
270
|
-
3. Test bus mode (new functionality)
|
|
271
|
-
4. Test mixed mode scenarios
|
|
272
|
-
5. Performance testing
|
|
273
|
-
|
|
274
|
-
### Phase 6: Examples & Documentation
|
|
275
|
-
1. Create example scripts
|
|
276
|
-
2. Update README
|
|
277
|
-
3. Update API documentation
|
|
278
|
-
4. Create migration guide
|
|
279
|
-
|
|
280
|
-
## Testing Commands
|
|
281
|
-
|
|
282
|
-
```bash
|
|
283
|
-
# Reinitialize database
|
|
284
|
-
nvm use 22 && node init-db.js
|
|
285
|
-
|
|
286
|
-
# Start server
|
|
287
|
-
nvm use 22 && npm start
|
|
288
|
-
|
|
289
|
-
# Run tests
|
|
290
|
-
nvm use 22 && node src/test/test.js
|
|
291
|
-
|
|
292
|
-
# Test bus mode
|
|
293
|
-
nvm use 22 && node examples/bus-mode.js
|
|
294
|
-
|
|
295
|
-
# Test mixed mode
|
|
296
|
-
nvm use 22 && node examples/mixed-mode.js
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
## Performance Considerations
|
|
300
|
-
|
|
301
|
-
### Optimizations
|
|
302
|
-
1. Use partial indexes for NULL/NOT NULL consumer_group
|
|
303
|
-
2. Batch status insertions for bus mode
|
|
304
|
-
3. Consider materialized views for message counts
|
|
305
|
-
4. Add connection pooling per consumer group
|
|
306
|
-
|
|
307
|
-
### Monitoring
|
|
308
|
-
1. Track consumer group lag
|
|
309
|
-
2. Monitor status table growth
|
|
310
|
-
3. Add metrics for queue vs bus mode usage
|
|
311
|
-
4. Dashboard updates for consumer groups
|
|
312
|
-
|
|
313
|
-
## Rollback Plan
|
|
314
|
-
1. Keep backup of original schema
|
|
315
|
-
2. Maintain backward compatibility
|
|
316
|
-
3. Feature flag for bus mode (optional)
|
|
317
|
-
4. Gradual rollout strategy
|
|
318
|
-
|
|
319
|
-
## Success Criteria
|
|
320
|
-
- [ ] All existing tests pass (backward compatibility)
|
|
321
|
-
- [ ] Queue mode works as before
|
|
322
|
-
- [ ] Bus mode delivers to all consumer groups
|
|
323
|
-
- [ ] Mixed mode works correctly
|
|
324
|
-
- [ ] Performance remains acceptable
|
|
325
|
-
- [ ] Documentation is complete
|
|
326
|
-
- [ ] Examples demonstrate all patterns
|
|
327
|
-
|
|
328
|
-
## Notes
|
|
329
|
-
- Consumer group = NULL is special case for queue mode
|
|
330
|
-
- Transaction ID moves to status table
|
|
331
|
-
- Messages table becomes immutable after insert
|
|
332
|
-
- Status table handles all mutable state
|
|
333
|
-
- Consider TTL for old status entries
|
|
334
|
-
- Add cleanup job for completed messages in bus mode
|
package/V2-PLAN.md
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
# Queen V2 Architecture Migration Plan
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
Restructuring the queue system from a rigid 3-tier hierarchy (Namespaces → Tasks → Queues) to a flexible 2-tier system (Queues → Partitions) with optional grouping fields.
|
|
5
|
-
|
|
6
|
-
## New Data Model
|
|
7
|
-
|
|
8
|
-
### Core Structure
|
|
9
|
-
```
|
|
10
|
-
Queues (with optional namespace/task grouping)
|
|
11
|
-
└── Partitions (FIFO ordering)
|
|
12
|
-
└── Messages
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
### Key Changes
|
|
16
|
-
1. **Remove** `namespaces` table
|
|
17
|
-
2. **Rename** `tasks` table → `queues` table
|
|
18
|
-
3. **Rename** `queues` table → `partitions` table
|
|
19
|
-
4. **Add** optional `namespace` and `task` fields to `queues` table for grouping
|
|
20
|
-
5. **Default Partition**: Each queue automatically gets a "Default" partition
|
|
21
|
-
|
|
22
|
-
## Database Schema Changes
|
|
23
|
-
|
|
24
|
-
### 1. Update schema.sql
|
|
25
|
-
- Drop the `namespaces` table
|
|
26
|
-
- Rename and restructure tables:
|
|
27
|
-
```sql
|
|
28
|
-
-- New queues table (was tasks)
|
|
29
|
-
CREATE TABLE queen.queues (
|
|
30
|
-
id UUID PRIMARY KEY,
|
|
31
|
-
name VARCHAR(255) UNIQUE NOT NULL,
|
|
32
|
-
namespace VARCHAR(255), -- optional grouping
|
|
33
|
-
task VARCHAR(255), -- optional grouping
|
|
34
|
-
created_at TIMESTAMP
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
-- New partitions table (was queues)
|
|
38
|
-
CREATE TABLE queen.partitions (
|
|
39
|
-
id UUID PRIMARY KEY,
|
|
40
|
-
queue_id UUID REFERENCES queen.queues(id),
|
|
41
|
-
name VARCHAR(255) NOT NULL DEFAULT 'Default',
|
|
42
|
-
priority INTEGER DEFAULT 0,
|
|
43
|
-
options JSONB,
|
|
44
|
-
created_at TIMESTAMP,
|
|
45
|
-
UNIQUE(queue_id, name)
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
-- Messages table stays similar, references partitions
|
|
49
|
-
CREATE TABLE queen.messages (
|
|
50
|
-
id UUID PRIMARY KEY,
|
|
51
|
-
partition_id UUID REFERENCES queen.partitions(id),
|
|
52
|
-
-- rest stays the same
|
|
53
|
-
);
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
### 2. Update Indexes
|
|
57
|
-
- Adjust all indexes to work with new structure
|
|
58
|
-
- Add indexes for optional namespace/task fields on queues table
|
|
59
|
-
- Maintain performance-critical indexes on messages table
|
|
60
|
-
|
|
61
|
-
## API Route Changes
|
|
62
|
-
|
|
63
|
-
### Push Routes
|
|
64
|
-
**Current**: `POST /api/v1/push`
|
|
65
|
-
```json
|
|
66
|
-
{
|
|
67
|
-
"items": [{
|
|
68
|
-
"ns": "namespace",
|
|
69
|
-
"task": "task",
|
|
70
|
-
"queue": "queue",
|
|
71
|
-
"payload": {}
|
|
72
|
-
}]
|
|
73
|
-
}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
**New**: `POST /api/v1/push`
|
|
77
|
-
```json
|
|
78
|
-
{
|
|
79
|
-
"items": [{
|
|
80
|
-
"queue": "queue",
|
|
81
|
-
"partition": "partition", // optional, defaults to "Default"
|
|
82
|
-
"payload": {}
|
|
83
|
-
}]
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Pop Routes
|
|
88
|
-
**Current**:
|
|
89
|
-
- `/api/v1/pop/ns/:ns/task/:task/queue/:queue`
|
|
90
|
-
- `/api/v1/pop/ns/:ns/task/:task`
|
|
91
|
-
- `/api/v1/pop/ns/:ns`
|
|
92
|
-
|
|
93
|
-
**New**:
|
|
94
|
-
- `/api/v1/pop/queue/:queue/partition/:partition` - Pop from specific partition
|
|
95
|
-
- `/api/v1/pop/queue/:queue` - Pop from any available partition in queue
|
|
96
|
-
- `/api/v1/pop?namespace=:ns` - Pop from any queue in namespace (optional filter)
|
|
97
|
-
- `/api/v1/pop?task=:task` - Pop from any queue in task (optional filter)
|
|
98
|
-
|
|
99
|
-
### Configure Routes
|
|
100
|
-
**Current**: `POST /api/v1/configure`
|
|
101
|
-
```json
|
|
102
|
-
{
|
|
103
|
-
"ns": "namespace",
|
|
104
|
-
"task": "task",
|
|
105
|
-
"queue": "queue",
|
|
106
|
-
"options": {}
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**New**: `POST /api/v1/configure`
|
|
111
|
-
```json
|
|
112
|
-
{
|
|
113
|
-
"queue": "queue",
|
|
114
|
-
"partition": "partition", // optional, defaults to "Default"
|
|
115
|
-
"options": {}
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### Analytics Routes
|
|
120
|
-
**Current**:
|
|
121
|
-
- `/api/v1/analytics/ns/:ns`
|
|
122
|
-
- `/api/v1/analytics/ns/:ns/task/:task`
|
|
123
|
-
|
|
124
|
-
**New**:
|
|
125
|
-
- `/api/v1/analytics/queue/:queue`
|
|
126
|
-
- `/api/v1/analytics?namespace=:ns` - Filter by namespace
|
|
127
|
-
- `/api/v1/analytics?task=:task` - Filter by task
|
|
128
|
-
|
|
129
|
-
## Code Changes Required
|
|
130
|
-
|
|
131
|
-
### 1. Database Layer (`src/database/`)
|
|
132
|
-
- [ ] Rewrite `schema.sql` with new structure
|
|
133
|
-
- [ ] Update `connection.js` initialization if needed
|
|
134
|
-
|
|
135
|
-
### 2. Manager Classes (`src/managers/`)
|
|
136
|
-
- [ ] Update `queueManagerOptimized.js`:
|
|
137
|
-
- [ ] Change `ensureResources()` to handle queue → partition structure
|
|
138
|
-
- [ ] Update `pushMessages()` to default to "Default" partition
|
|
139
|
-
- [ ] Modify `popMessages()` for new partition logic
|
|
140
|
-
- [ ] Adjust `getQueueStats()` for new structure
|
|
141
|
-
- [ ] Update `resourceCache.js`:
|
|
142
|
-
- [ ] Change cache key format from `ns:task:queue` to `queue:partition`
|
|
143
|
-
- [ ] Update `eventManager.js`:
|
|
144
|
-
- [ ] Adjust event paths from `ns/task/queue` to `queue/partition`
|
|
145
|
-
|
|
146
|
-
### 3. Route Handlers (`src/routes/`)
|
|
147
|
-
- [ ] Update `push.js`:
|
|
148
|
-
- [ ] Remove ns/task requirements
|
|
149
|
-
- [ ] Add partition defaulting logic
|
|
150
|
-
- [ ] Update `pop.js`:
|
|
151
|
-
- [ ] New route parameter structure
|
|
152
|
-
- [ ] Implement "any available partition" logic
|
|
153
|
-
- [ ] Update `configure.js`:
|
|
154
|
-
- [ ] Work with queue/partition instead of ns/task/queue
|
|
155
|
-
- [ ] Update `analytics.js`:
|
|
156
|
-
- [ ] New aggregation logic based on optional namespace/task fields
|
|
157
|
-
- [ ] Update `messages.js`:
|
|
158
|
-
- [ ] Adjust queries for new structure
|
|
159
|
-
|
|
160
|
-
### 4. Server (`src/server.js`)
|
|
161
|
-
- [ ] Update all route definitions
|
|
162
|
-
- [ ] Adjust URL patterns
|
|
163
|
-
- [ ] Update WebSocket event paths
|
|
164
|
-
|
|
165
|
-
### 5. Client Library (`src/client/`)
|
|
166
|
-
- [ ] Update `queenClient.js` with new API structure
|
|
167
|
-
- [ ] Adjust method signatures
|
|
168
|
-
|
|
169
|
-
### 6. WebSocket (`src/websocket/`)
|
|
170
|
-
- [ ] Update event naming and paths
|
|
171
|
-
- [ ] Adjust queue depth updates
|
|
172
|
-
|
|
173
|
-
## Implementation Order
|
|
174
|
-
|
|
175
|
-
1. **Database Schema**
|
|
176
|
-
- Create new `schema-v2.sql`
|
|
177
|
-
- Test schema independently
|
|
178
|
-
|
|
179
|
-
2. **Core Manager Updates**
|
|
180
|
-
- Update `queueManagerOptimized.js` with new logic
|
|
181
|
-
- Update resource caching
|
|
182
|
-
- Update event manager
|
|
183
|
-
|
|
184
|
-
3. **Route Handlers**
|
|
185
|
-
- Update each route file for new structure
|
|
186
|
-
- Maintain backwards compatibility temporarily if needed
|
|
187
|
-
|
|
188
|
-
4. **Server Integration**
|
|
189
|
-
- Update `server.js` with new routes
|
|
190
|
-
- Test each endpoint
|
|
191
|
-
|
|
192
|
-
5. **Client Updates**
|
|
193
|
-
- Update client library
|
|
194
|
-
- Update examples
|
|
195
|
-
|
|
196
|
-
6. **Frontend Updates**
|
|
197
|
-
- Update API calls in frontend
|
|
198
|
-
- Adjust data structures
|
|
199
|
-
|
|
200
|
-
## Partition Selection Logic
|
|
201
|
-
|
|
202
|
-
When popping from a queue (without specifying partition):
|
|
203
|
-
1. Select the partition with the oldest pending message
|
|
204
|
-
2. Use `ORDER BY created_at ASC` across partitions
|
|
205
|
-
3. Maintain FIFO within each partition
|
|
206
|
-
4. Use `FOR UPDATE SKIP LOCKED` for concurrency
|
|
207
|
-
|
|
208
|
-
## Default Partition Behavior
|
|
209
|
-
|
|
210
|
-
1. **Auto-creation**: When a queue is created, automatically create a "Default" partition
|
|
211
|
-
2. **Push behavior**: If no partition specified, use "Default"
|
|
212
|
-
3. **Pop behavior**: Include "Default" when popping from queue level
|
|
213
|
-
|
|
214
|
-
## Node
|
|
215
|
-
Always use "nvm use 22 && your node.js command"
|
|
216
|
-
|
|
217
|
-
## Testing Checklist
|
|
218
|
-
|
|
219
|
-
- [ ] Push to queue with no partition (should use Default)
|
|
220
|
-
- [ ] Push to specific partition
|
|
221
|
-
- [ ] Pop from specific partition
|
|
222
|
-
- [ ] Pop from queue (any partition)
|
|
223
|
-
- [ ] Queue configuration
|
|
224
|
-
- [ ] Partition configuration
|
|
225
|
-
- [ ] Analytics with namespace filtering
|
|
226
|
-
- [ ] Analytics with task filtering
|
|
227
|
-
- [ ] Message acknowledgment
|
|
228
|
-
- [ ] Batch operations
|
|
229
|
-
- [ ] WebSocket events
|
|
230
|
-
- [ ] Long polling
|
|
231
|
-
- [ ] Lease expiration
|
|
232
|
-
- [ ] Performance with multiple partitions
|
|
233
|
-
|
|
234
|
-
## Migration Notes
|
|
235
|
-
|
|
236
|
-
- No data migration needed (starting fresh)
|
package/dashboard/README.md
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
# Vue 3 + Vite
|
|
2
|
-
|
|
3
|
-
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
|
4
|
-
|
|
5
|
-
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).
|
package/dashboard/index.html
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
|
7
|
-
<title>Queen Dashboard - Message Queue Management</title>
|
|
8
|
-
<meta name="description" content="Real-time monitoring and management dashboard for Queen Message Queue System">
|
|
9
|
-
</head>
|
|
10
|
-
<body>
|
|
11
|
-
<div id="app"></div>
|
|
12
|
-
<script type="module" src="/src/main.js"></script>
|
|
13
|
-
</body>
|
|
14
|
-
</html>
|