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.
- package/API.md +1116 -0
- package/CACHE.md +519 -0
- package/DASHBOARD-V3.md +478 -0
- package/DASHBOARD.md +382 -0
- package/MOD_QUEUE.md +453 -0
- package/PARTITION_LOCKING_DESIGN.md +989 -0
- package/PLAN.md +707 -0
- package/QUERY_ANALSYS.md +72 -0
- package/QUEUE_BUS.md +334 -0
- package/README.md +1495 -0
- package/V2-PLAN.md +236 -0
- package/assets/dashboard.png +0 -0
- package/dashboard/.vscode/extensions.json +3 -0
- package/dashboard/README.md +5 -0
- package/dashboard/index.html +14 -0
- package/dashboard/package-lock.json +1458 -0
- package/dashboard/package.json +25 -0
- package/dashboard/public/vite.svg +1 -0
- package/dashboard/src/App.vue +29 -0
- package/dashboard/src/assets/styles/main.css +908 -0
- package/dashboard/src/assets/vue.svg +1 -0
- package/dashboard/src/components/cards/MetricCard.vue +298 -0
- package/dashboard/src/components/charts/QueueDepthChart.vue +276 -0
- package/dashboard/src/components/charts/QueueLagChart.vue +436 -0
- package/dashboard/src/components/charts/ThroughputChart.vue +302 -0
- package/dashboard/src/components/common/ActivityFeed.vue +251 -0
- package/dashboard/src/components/layout/AppHeader.vue +208 -0
- package/dashboard/src/components/layout/AppLayout.vue +88 -0
- package/dashboard/src/components/layout/AppSidebar.vue +261 -0
- package/dashboard/src/main.js +44 -0
- package/dashboard/src/router.js +54 -0
- package/dashboard/src/services/api.js +187 -0
- package/dashboard/src/services/websocket.js +167 -0
- package/dashboard/src/utils/constants.js +56 -0
- package/dashboard/src/utils/helpers.js +118 -0
- package/dashboard/src/views/Analytics.vue +912 -0
- package/dashboard/src/views/Dashboard.vue +906 -0
- package/dashboard/src/views/Messages.vue +437 -0
- package/dashboard/src/views/QueueDetail.vue +501 -0
- package/dashboard/src/views/Queues.vue +333 -0
- package/dashboard/vite.config.js +30 -0
- package/debug-namespace.js +110 -0
- package/docs/long-polling.md +159 -0
- package/docs/multi-server-cache-solutions.md +185 -0
- package/docs/performance-tuning.md +222 -0
- package/examples/bus-mode.js +239 -0
- package/examples/continuous-consumer-optimized.js +215 -0
- package/examples/continuous-consumer.js +159 -0
- package/examples/continuous-producer.js +343 -0
- package/examples/mixed-mode.js +277 -0
- package/examples/multi-server-test.js +305 -0
- package/examples/single.js +64 -0
- package/examples/smartchat-dealyed.js +42 -0
- package/examples/smartchat.js +52 -0
- package/examples/test-cache-invalidation.js +119 -0
- package/examples/test-cache-multi-server.js +245 -0
- package/examples/test-minimal-client.js +112 -0
- package/examples/test-queue-creation-policy.js +137 -0
- package/init-db.js +20 -0
- package/package.json +36 -0
- package/src/client/client.js +291 -0
- package/src/client/index.js +6 -0
- package/src/client/queenClient.js +513 -0
- package/src/client/utils/http.js +172 -0
- package/src/client/utils/loadBalancer.js +152 -0
- package/src/client/utils/retry.js +35 -0
- package/src/config.js +215 -0
- package/src/database/connection.js +103 -0
- package/src/database/poolManager.js +192 -0
- package/src/database/schema-v2.sql +214 -0
- package/src/managers/eventManager.js +59 -0
- package/src/managers/queueManagerOptimized.js +1512 -0
- package/src/managers/resourceCache.js +96 -0
- package/src/managers/systemEventManager.js +127 -0
- package/src/routes/ack.js +26 -0
- package/src/routes/analytics.js +812 -0
- package/src/routes/configure.js +46 -0
- package/src/routes/messages.js +298 -0
- package/src/routes/pop.js +85 -0
- package/src/routes/push.js +28 -0
- package/src/routes/resources.js +296 -0
- package/src/server.js +1286 -0
- package/src/services/encryptionService.js +82 -0
- package/src/services/evictionService.js +131 -0
- package/src/services/retentionService.js +129 -0
- package/src/services/startupSync.js +35 -0
- package/src/test/test.js +4521 -0
- package/src/utils/logger.js +44 -0
- package/src/utils/uuid.js +5 -0
- package/src/websocket/wsServer.js +221 -0
package/QUERY_ANALSYS.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
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
|