queen-mq 0.1.5 → 0.2.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/README.md +467 -1775
- package/package.json +12 -14
- package/src/client/client.js +664 -5
- package/src/managers/queueManagerOptimized.js +250 -47
- package/src/routes/ack.js +3 -3
- package/src/server.js +131 -3
- package/src/test/advanced-client-tests.js +761 -0
- package/src/test/advanced-pattern-tests.js +2 -2
- package/src/test/bus-mode-tests.js +6 -6
- package/src/test/core-tests.js +1 -1
- package/src/test/edge-case-tests.js +2 -2
- package/src/test/test-new.js +36 -1
- package/src/webapp-dist/assets/Analytics-DJrE4Rz2.css +1 -0
- package/src/webapp-dist/assets/Analytics-HEMXKmfJ.js +1 -0
- package/src/webapp-dist/assets/ConfirmDialog-YEoCdE7x.js +1 -0
- package/src/webapp-dist/assets/ConsumerGroups-CC5VJywp.css +1 -0
- package/src/webapp-dist/assets/ConsumerGroups-D8Z20HhZ.js +1 -0
- package/src/webapp-dist/assets/Dashboard-BRFOz6it.css +1 -0
- package/src/webapp-dist/assets/Dashboard-Bpx9I32h.js +1 -0
- package/src/webapp-dist/assets/LoadingSpinner-BPttXcbs.js +1 -0
- package/src/webapp-dist/assets/Messages-BOfVHKma.css +1 -0
- package/src/webapp-dist/assets/Messages-EKURCbLl.js +1 -0
- package/src/webapp-dist/assets/QueueDetail-BXXA7xoZ.css +1 -0
- package/src/webapp-dist/assets/QueueDetail-Bmxg0KiA.js +1 -0
- package/src/webapp-dist/assets/Queues-CvrJkrZT.css +1 -0
- package/src/webapp-dist/assets/Queues-yUx9_3-9.js +1 -0
- package/src/webapp-dist/assets/StatusBadge-C1bBtXHh.css +1 -0
- package/src/webapp-dist/assets/StatusBadge-C6N84XmO.js +1 -0
- package/src/webapp-dist/assets/analytics-BapTekLM.js +1 -0
- package/src/webapp-dist/assets/colors-5z6Q_kUr.js +18 -0
- package/src/webapp-dist/assets/index-B7w2bKT6.css +1 -0
- package/src/webapp-dist/assets/index-CUSnwYTH.js +31 -0
- package/src/webapp-dist/assets/messages-CRV6E-xU.js +1 -0
- package/src/webapp-dist/assets/queues-BdUbxfBC.js +1 -0
- package/src/webapp-dist/assets/resources-Bs9U-ceF.js +1 -0
- package/{webapp → src/webapp-dist}/index.html +2 -1
- package/API.md +0 -1226
- package/AUTH.md +0 -2044
- package/CHANGELOG_STATIC_SERVING.md +0 -213
- package/DEPLOYMENT.md +0 -425
- package/PROGRAMMATIC_SERVER.md +0 -239
- package/WEBAPP.md +0 -1889
- package/assets/dashboard-01.png +0 -0
- package/assets/dashboard.png +0 -0
- package/examples/batch-processing.js +0 -58
- package/examples/bus-mode.js +0 -239
- package/examples/continuous-consumer-optimized.js +0 -215
- package/examples/continuous-consumer.js +0 -159
- package/examples/continuous-producer.js +0 -343
- package/examples/mixed-mode.js +0 -277
- package/examples/multi-server-test.js +0 -305
- package/examples/programmatic-server.js +0 -58
- package/examples/server-with-frontend.js +0 -46
- package/examples/single.js +0 -64
- package/examples/smartchat-dealyed.js +0 -42
- package/examples/smartchat.js +0 -52
- package/examples/test-cache-invalidation.js +0 -119
- package/examples/test-cache-multi-server.js +0 -245
- package/examples/test-complete-client.js +0 -260
- package/examples/test-connection-recovery.js +0 -66
- package/examples/test-dashboard-api.js +0 -200
- package/examples/test-minimal-client.js +0 -112
- package/examples/test-queue-creation-policy.js +0 -137
- package/examples/test-traceid.js +0 -147
- package/server.log +0 -1
- package/test-keepalive-v2.sh +0 -22
- package/webapp/COLOR_GUIDE.md +0 -118
- package/webapp/README.md +0 -143
- package/webapp/package-lock.json +0 -3184
- package/webapp/package.json +0 -25
- package/webapp/postcss.config.js +0 -7
- package/webapp/public/assets/queen-logo-blue.svg +0 -210
- package/webapp/public/assets/queen-logo-cyan.svg +0 -210
- package/webapp/public/assets/queen-logo-indigo.svg +0 -210
- package/webapp/public/assets/queen-logo-orange.svg +0 -210
- package/webapp/public/assets/queen-logo-pink.svg +0 -210
- package/webapp/public/assets/queen-logo-purple.svg +0 -210
- package/webapp/public/assets/queen-logo-rose.svg +0 -239
- package/webapp/public/assets/queen-logo.svg +0 -263
- package/webapp/src/App.vue +0 -19
- package/webapp/src/api/analytics.js +0 -10
- package/webapp/src/api/client.js +0 -34
- package/webapp/src/api/consumers.js +0 -52
- package/webapp/src/api/health.js +0 -7
- package/webapp/src/api/messages.js +0 -26
- package/webapp/src/api/queues.js +0 -14
- package/webapp/src/api/resources.js +0 -8
- package/webapp/src/assets/styles/main.css +0 -357
- package/webapp/src/components/analytics/AnalyticsFilters.vue +0 -87
- package/webapp/src/components/analytics/AnalyticsMetrics.vue +0 -57
- package/webapp/src/components/analytics/MessageDistributionChart.vue +0 -111
- package/webapp/src/components/analytics/MessageFlowChart.vue +0 -173
- package/webapp/src/components/analytics/TimeRangeSelector.vue +0 -27
- package/webapp/src/components/analytics/TopQueuesChart.vue +0 -132
- package/webapp/src/components/common/ConfirmDialog.vue +0 -56
- package/webapp/src/components/common/LoadingSpinner.vue +0 -6
- package/webapp/src/components/common/MetricCard.vue +0 -43
- package/webapp/src/components/common/StatusBadge.vue +0 -45
- package/webapp/src/components/dashboard/MessageStatusCard.vue +0 -50
- package/webapp/src/components/dashboard/PerformanceCard.vue +0 -38
- package/webapp/src/components/dashboard/ThroughputChart.vue +0 -182
- package/webapp/src/components/dashboard/TopQueuesTable.vue +0 -53
- package/webapp/src/components/layout/AppLayout.vue +0 -110
- package/webapp/src/components/layout/AppSidebar.vue +0 -304
- package/webapp/src/components/messages/MessageDetailPanel.vue +0 -242
- package/webapp/src/components/messages/MessageFilters.vue +0 -101
- package/webapp/src/components/queue-detail/PartitionList.vue +0 -79
- package/webapp/src/components/queue-detail/PushMessageModal.vue +0 -175
- package/webapp/src/components/queue-detail/QueueConfig.vue +0 -63
- package/webapp/src/components/queue-detail/QueueDetailHeader.vue +0 -53
- package/webapp/src/components/queue-detail/RecentMessages.vue +0 -76
- package/webapp/src/components/queues/CreateQueueModal.vue +0 -193
- package/webapp/src/components/queues/QueueFilters.vue +0 -90
- package/webapp/src/composables/useApi.js +0 -34
- package/webapp/src/composables/useTheme.js +0 -36
- package/webapp/src/main.js +0 -11
- package/webapp/src/router/index.js +0 -42
- package/webapp/src/utils/colors.js +0 -96
- package/webapp/src/utils/formatters.js +0 -49
- package/webapp/src/views/Analytics.vue +0 -377
- package/webapp/src/views/ConsumerGroups.vue +0 -433
- package/webapp/src/views/Dashboard.vue +0 -418
- package/webapp/src/views/Messages.vue +0 -363
- package/webapp/src/views/QueueDetail.vue +0 -582
- package/webapp/src/views/Queues.vue +0 -496
- package/webapp/tailwind.config.js +0 -25
- package/webapp/vite.config.js +0 -10
- /package/{assets → src/webapp-dist/assets}/queen-logo-blue.svg +0 -0
- /package/{assets → src/webapp-dist/assets}/queen-logo-cyan.svg +0 -0
- /package/{assets → src/webapp-dist/assets}/queen-logo-indigo.svg +0 -0
- /package/{assets → src/webapp-dist/assets}/queen-logo-orange.svg +0 -0
- /package/{assets → src/webapp-dist/assets}/queen-logo-pink.svg +0 -0
- /package/{assets → src/webapp-dist/assets}/queen-logo-purple.svg +0 -0
- /package/{assets → src/webapp-dist/assets}/queen-logo-rose.svg +0 -0
- /package/{assets → src/webapp-dist/assets}/queen-logo.svg +0 -0
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test script for the new Dashboard Status API endpoints
|
|
3
|
-
*
|
|
4
|
-
* This script demonstrates all 5 new endpoints:
|
|
5
|
-
* 1. GET /api/v1/status - Dashboard overview
|
|
6
|
-
* 2. GET /api/v1/status/queues - List queues with stats
|
|
7
|
-
* 3. GET /api/v1/status/queues/:queue - Queue detail
|
|
8
|
-
* 4. GET /api/v1/status/queues/:queue/messages - Queue messages
|
|
9
|
-
* 5. GET /api/v1/status/analytics - Advanced analytics
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { createQueenClient } from '../src/client/queenClient.js';
|
|
13
|
-
|
|
14
|
-
const BASE_URL = process.env.QUEEN_URL || 'http://localhost:3000';
|
|
15
|
-
|
|
16
|
-
// Create client
|
|
17
|
-
const client = createQueenClient({ baseUrl: BASE_URL });
|
|
18
|
-
|
|
19
|
-
// Helper to make GET requests
|
|
20
|
-
async function get(path) {
|
|
21
|
-
const response = await fetch(`${BASE_URL}${path}`, {
|
|
22
|
-
method: 'GET',
|
|
23
|
-
headers: {
|
|
24
|
-
'Content-Type': 'application/json'
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
if (!response.ok) {
|
|
29
|
-
const error = await response.text();
|
|
30
|
-
throw new Error(`HTTP ${response.status}: ${error}`);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return await response.json();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Helper to format JSON output
|
|
37
|
-
function printJson(label, data) {
|
|
38
|
-
console.log(`\n${'='.repeat(80)}`);
|
|
39
|
-
console.log(`📊 ${label}`);
|
|
40
|
-
console.log('='.repeat(80));
|
|
41
|
-
console.log(JSON.stringify(data, null, 2));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function runTests() {
|
|
45
|
-
console.log('🚀 Testing Queen Dashboard Status API\n');
|
|
46
|
-
|
|
47
|
-
try {
|
|
48
|
-
// First, let's create some test data
|
|
49
|
-
console.log('📝 Setting up test data...');
|
|
50
|
-
|
|
51
|
-
// Configure a test queue
|
|
52
|
-
await client.configure({
|
|
53
|
-
queue: 'dashboard-test-queue',
|
|
54
|
-
namespace: 'test-namespace',
|
|
55
|
-
task: 'test-task',
|
|
56
|
-
partitions: 3
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
// Push some test messages
|
|
60
|
-
const messages = [];
|
|
61
|
-
for (let i = 0; i < 20; i++) {
|
|
62
|
-
messages.push({
|
|
63
|
-
queue: 'dashboard-test-queue',
|
|
64
|
-
partition: `partition-${i % 3}`,
|
|
65
|
-
payload: {
|
|
66
|
-
messageNumber: i,
|
|
67
|
-
timestamp: new Date().toISOString(),
|
|
68
|
-
data: `Test message ${i}`
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
await client.pushBatch(messages);
|
|
74
|
-
console.log('✅ Created test queue with 20 messages\n');
|
|
75
|
-
|
|
76
|
-
// Wait a bit for messages to be processed
|
|
77
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
78
|
-
|
|
79
|
-
// Test 1: Dashboard Status
|
|
80
|
-
console.log('🧪 Test 1: Dashboard Status (GET /api/v1/status)');
|
|
81
|
-
const status = await get('/api/v1/status');
|
|
82
|
-
printJson('Dashboard Status', {
|
|
83
|
-
timeRange: status.timeRange,
|
|
84
|
-
queuesCount: status.queues.length,
|
|
85
|
-
messages: status.messages,
|
|
86
|
-
leases: status.leases,
|
|
87
|
-
throughputSamples: status.throughput.length,
|
|
88
|
-
dlqTotal: status.deadLetterQueue.totalMessages
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// Test 2: Queues List
|
|
92
|
-
console.log('\n🧪 Test 2: List Queues (GET /api/v1/status/queues)');
|
|
93
|
-
const queues = await get('/api/v1/status/queues?limit=10');
|
|
94
|
-
printJson('Queues List', {
|
|
95
|
-
total: queues.pagination.total,
|
|
96
|
-
queues: queues.queues.map(q => ({
|
|
97
|
-
name: q.name,
|
|
98
|
-
namespace: q.namespace,
|
|
99
|
-
partitions: q.partitions,
|
|
100
|
-
pending: q.messages.pending,
|
|
101
|
-
completed: q.messages.completed
|
|
102
|
-
}))
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Test 3: Queue Detail
|
|
106
|
-
console.log('\n🧪 Test 3: Queue Detail (GET /api/v1/status/queues/:queue)');
|
|
107
|
-
const queueDetail = await get('/api/v1/status/queues/dashboard-test-queue');
|
|
108
|
-
printJson('Queue Detail', {
|
|
109
|
-
queue: queueDetail.queue,
|
|
110
|
-
totals: queueDetail.totals,
|
|
111
|
-
partitionCount: queueDetail.partitions.length,
|
|
112
|
-
partitions: queueDetail.partitions.map(p => ({
|
|
113
|
-
name: p.name,
|
|
114
|
-
messages: p.messages,
|
|
115
|
-
cursor: p.cursor
|
|
116
|
-
}))
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
// Test 4: Queue Messages
|
|
120
|
-
console.log('\n🧪 Test 4: Queue Messages (GET /api/v1/status/queues/:queue/messages)');
|
|
121
|
-
const messages_result = await get('/api/v1/status/queues/dashboard-test-queue/messages?limit=5');
|
|
122
|
-
printJson('Queue Messages', {
|
|
123
|
-
total: messages_result.pagination.total,
|
|
124
|
-
showing: messages_result.messages.length,
|
|
125
|
-
messages: messages_result.messages.map(m => ({
|
|
126
|
-
transactionId: m.transactionId,
|
|
127
|
-
partition: m.partition,
|
|
128
|
-
status: m.status,
|
|
129
|
-
createdAt: m.createdAt
|
|
130
|
-
}))
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// Test 5: Filter by status
|
|
134
|
-
console.log('\n🧪 Test 5: Filter Messages by Status (GET /api/v1/status/queues/:queue/messages?status=pending)');
|
|
135
|
-
const pendingMessages = await get('/api/v1/status/queues/dashboard-test-queue/messages?status=pending&limit=5');
|
|
136
|
-
printJson('Pending Messages', {
|
|
137
|
-
total: pendingMessages.pagination.total,
|
|
138
|
-
messages: pendingMessages.messages.map(m => ({
|
|
139
|
-
transactionId: m.transactionId,
|
|
140
|
-
status: m.status,
|
|
141
|
-
age: m.age
|
|
142
|
-
}))
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
// Test 6: Analytics (last hour with minute interval)
|
|
146
|
-
console.log('\n🧪 Test 6: Analytics (GET /api/v1/status/analytics?interval=minute)');
|
|
147
|
-
const analytics = await get('/api/v1/status/analytics?interval=minute');
|
|
148
|
-
printJson('Analytics Overview', {
|
|
149
|
-
timeRange: analytics.timeRange,
|
|
150
|
-
throughput: {
|
|
151
|
-
totals: analytics.throughput.totals,
|
|
152
|
-
recentSamples: analytics.throughput.timeSeries.slice(0, 3)
|
|
153
|
-
},
|
|
154
|
-
latency: analytics.latency.overall,
|
|
155
|
-
errorRates: analytics.errorRates.overall,
|
|
156
|
-
currentDepth: analytics.queueDepths.current,
|
|
157
|
-
topQueues: analytics.topQueues.slice(0, 3),
|
|
158
|
-
dlqTotal: analytics.deadLetterQueue.total
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
// Test 7: Filter by namespace
|
|
162
|
-
console.log('\n🧪 Test 7: Dashboard Status filtered by namespace (GET /api/v1/status?namespace=test-namespace)');
|
|
163
|
-
const statusFiltered = await get('/api/v1/status?namespace=test-namespace');
|
|
164
|
-
printJson('Filtered Status', {
|
|
165
|
-
queuesCount: statusFiltered.queues.length,
|
|
166
|
-
queues: statusFiltered.queues.map(q => q.name),
|
|
167
|
-
messages: statusFiltered.messages
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// Test 8: Analytics with time range
|
|
171
|
-
console.log('\n🧪 Test 8: Analytics with custom time range (last 30 minutes)');
|
|
172
|
-
const thirtyMinutesAgo = new Date(Date.now() - 30 * 60 * 1000).toISOString();
|
|
173
|
-
const now = new Date().toISOString();
|
|
174
|
-
const analyticsTimeRange = await get(`/api/v1/status/analytics?from=${thirtyMinutesAgo}&to=${now}&interval=minute`);
|
|
175
|
-
printJson('Analytics (Last 30 min)', {
|
|
176
|
-
timeRange: analyticsTimeRange.timeRange,
|
|
177
|
-
throughputSamples: analyticsTimeRange.throughput.timeSeries.length,
|
|
178
|
-
totals: analyticsTimeRange.throughput.totals
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
console.log('\n' + '='.repeat(80));
|
|
182
|
-
console.log('✅ All tests completed successfully!');
|
|
183
|
-
console.log('='.repeat(80));
|
|
184
|
-
|
|
185
|
-
} catch (error) {
|
|
186
|
-
console.error('\n❌ Test failed:', error.message);
|
|
187
|
-
console.error(error.stack);
|
|
188
|
-
process.exit(1);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Run tests
|
|
193
|
-
runTests().then(() => {
|
|
194
|
-
console.log('\n✨ Dashboard API test complete!');
|
|
195
|
-
process.exit(0);
|
|
196
|
-
}).catch(error => {
|
|
197
|
-
console.error('Fatal error:', error);
|
|
198
|
-
process.exit(1);
|
|
199
|
-
});
|
|
200
|
-
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Test the minimalist Queen client interface
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { Queen } from '../src/client/client.js';
|
|
8
|
-
|
|
9
|
-
async function main() {
|
|
10
|
-
console.log('🧪 Testing Minimalist Queen Client\n');
|
|
11
|
-
|
|
12
|
-
// Create client instance
|
|
13
|
-
const client = new Queen({
|
|
14
|
-
baseUrls: ['http://localhost:6632'],
|
|
15
|
-
timeout: 30000,
|
|
16
|
-
retryAttempts: 3,
|
|
17
|
-
retryDelay: 1000
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const testQueue = 'test-minimal-' + Date.now();
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
// 1. Configure queue
|
|
24
|
-
console.log('1️⃣ Configuring queue...');
|
|
25
|
-
await client.queue(testQueue, {
|
|
26
|
-
leaseTime: 300,
|
|
27
|
-
retryLimit: 3,
|
|
28
|
-
retryDelay: 1000
|
|
29
|
-
});
|
|
30
|
-
console.log('✅ Queue configured:', testQueue);
|
|
31
|
-
|
|
32
|
-
// 2. Push single message
|
|
33
|
-
console.log('\n2️⃣ Pushing single message...');
|
|
34
|
-
await client.push(testQueue, {
|
|
35
|
-
id: 1,
|
|
36
|
-
message: 'Hello, Queen!',
|
|
37
|
-
timestamp: new Date().toISOString()
|
|
38
|
-
});
|
|
39
|
-
console.log('✅ Single message pushed');
|
|
40
|
-
|
|
41
|
-
// 3. Push batch of messages
|
|
42
|
-
console.log('\n3️⃣ Pushing batch of messages...');
|
|
43
|
-
const batch = [
|
|
44
|
-
{ id: 2, message: 'Message 2' },
|
|
45
|
-
{ id: 3, message: 'Message 3' },
|
|
46
|
-
{ id: 4, message: 'Message 4' }
|
|
47
|
-
];
|
|
48
|
-
await client.push(testQueue, batch);
|
|
49
|
-
console.log('✅ Batch of 3 messages pushed');
|
|
50
|
-
|
|
51
|
-
// 4. Push to specific partition
|
|
52
|
-
console.log('\n4️⃣ Pushing to urgent partition...');
|
|
53
|
-
await client.push(`${testQueue}/urgent`, {
|
|
54
|
-
id: 5,
|
|
55
|
-
message: 'Urgent message!',
|
|
56
|
-
priority: 'high'
|
|
57
|
-
});
|
|
58
|
-
console.log('✅ Message pushed to urgent partition');
|
|
59
|
-
|
|
60
|
-
// 5. Take messages with limit
|
|
61
|
-
console.log('\n5️⃣ Taking 3 messages...');
|
|
62
|
-
let count = 0;
|
|
63
|
-
for await (const message of client.take(testQueue, { limit: 3 })) {
|
|
64
|
-
count++;
|
|
65
|
-
console.log(` 📩 Message ${count}:`, message.data);
|
|
66
|
-
await client.ack(message);
|
|
67
|
-
}
|
|
68
|
-
console.log('✅ Took and acknowledged 3 messages');
|
|
69
|
-
|
|
70
|
-
// 6. Take from specific partition
|
|
71
|
-
console.log('\n6️⃣ Taking from urgent partition...');
|
|
72
|
-
for await (const message of client.take(`${testQueue}/urgent`, { limit: 1 })) {
|
|
73
|
-
console.log(' 🚨 Urgent message:', message.data);
|
|
74
|
-
await client.ack(message, true);
|
|
75
|
-
}
|
|
76
|
-
console.log('✅ Processed urgent message');
|
|
77
|
-
|
|
78
|
-
// 7. Test failure acknowledgment
|
|
79
|
-
console.log('\n7️⃣ Testing failure acknowledgment...');
|
|
80
|
-
await client.push(testQueue, { id: 6, message: 'Will fail' });
|
|
81
|
-
|
|
82
|
-
for await (const message of client.take(testQueue, { limit: 1 })) {
|
|
83
|
-
console.log(' ❌ Simulating failure for:', message.data);
|
|
84
|
-
await client.ack(message, false, { error: 'Simulated error' });
|
|
85
|
-
}
|
|
86
|
-
console.log('✅ Failed acknowledgment sent');
|
|
87
|
-
|
|
88
|
-
// 8. Test consumer groups (if needed)
|
|
89
|
-
console.log('\n8️⃣ Testing consumer groups...');
|
|
90
|
-
await client.push(testQueue, { id: 7, message: 'For consumer group' });
|
|
91
|
-
|
|
92
|
-
for await (const message of client.take(`${testQueue}@test-group`, { limit: 1 })) {
|
|
93
|
-
console.log(' 👥 Message via consumer group:', message.data);
|
|
94
|
-
await client.ack(message, true, { group: 'test-group' });
|
|
95
|
-
}
|
|
96
|
-
console.log('✅ Consumer group test complete');
|
|
97
|
-
|
|
98
|
-
console.log('\n🎉 All tests passed!');
|
|
99
|
-
|
|
100
|
-
} catch (error) {
|
|
101
|
-
console.error('\n❌ Test failed:', error.message);
|
|
102
|
-
process.exit(1);
|
|
103
|
-
} finally {
|
|
104
|
-
await client.close();
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Run tests
|
|
109
|
-
main().catch(error => {
|
|
110
|
-
console.error('Fatal error:', error);
|
|
111
|
-
process.exit(1);
|
|
112
|
-
});
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Test script to verify the new queue creation policy:
|
|
5
|
-
* - Queues must be created via configure endpoint
|
|
6
|
-
* - Push to non-existent queue should fail
|
|
7
|
-
* - Partitions can still be created on-demand
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { createQueenClient } from '../src/client/index.js';
|
|
11
|
-
|
|
12
|
-
const TEST_QUEUE = 'test-creation-policy';
|
|
13
|
-
const NON_EXISTENT_QUEUE = 'queue-that-does-not-exist';
|
|
14
|
-
|
|
15
|
-
// Helper to log with timestamp
|
|
16
|
-
const log = (message, type = 'info') => {
|
|
17
|
-
const timestamp = new Date().toISOString().split('T')[1].slice(0, -1);
|
|
18
|
-
const prefix = type === 'error' ? '❌' : type === 'success' ? '✅' : 'ℹ️';
|
|
19
|
-
console.log(`${timestamp} | ${prefix} ${message}`);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
async function runTests() {
|
|
23
|
-
console.log('=' .repeat(80));
|
|
24
|
-
console.log('Testing Queue Creation Policy');
|
|
25
|
-
console.log('=' .repeat(80));
|
|
26
|
-
|
|
27
|
-
const client = createQueenClient({
|
|
28
|
-
baseUrl: 'http://localhost:6632'
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
// Test 1: Push to non-existent queue should fail
|
|
33
|
-
log('\nTest 1: Pushing to non-existent queue (should fail)...');
|
|
34
|
-
try {
|
|
35
|
-
await client.push({
|
|
36
|
-
items: [{
|
|
37
|
-
queue: NON_EXISTENT_QUEUE,
|
|
38
|
-
partition: 'Default',
|
|
39
|
-
payload: { test: 'should fail' }
|
|
40
|
-
}]
|
|
41
|
-
});
|
|
42
|
-
log('Push succeeded unexpectedly!', 'error');
|
|
43
|
-
process.exit(1);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
if (error.message.includes('does not exist')) {
|
|
46
|
-
log(`Push failed as expected: ${error.message}`, 'success');
|
|
47
|
-
} else {
|
|
48
|
-
log(`Push failed with unexpected error: ${error.message}`, 'error');
|
|
49
|
-
throw error;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Test 2: Create queue via configure
|
|
54
|
-
log('\nTest 2: Creating queue via configure endpoint...');
|
|
55
|
-
const configResult = await client.configure({
|
|
56
|
-
queue: TEST_QUEUE,
|
|
57
|
-
namespace: 'test',
|
|
58
|
-
task: 'creation-policy',
|
|
59
|
-
options: {
|
|
60
|
-
retryLimit: 3,
|
|
61
|
-
priority: 5
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
log(`Queue configured: ${JSON.stringify(configResult)}`, 'success');
|
|
65
|
-
|
|
66
|
-
// Test 3: Push to configured queue should succeed
|
|
67
|
-
log('\nTest 3: Pushing to configured queue (should succeed)...');
|
|
68
|
-
const pushResult1 = await client.push({
|
|
69
|
-
items: [{
|
|
70
|
-
queue: TEST_QUEUE,
|
|
71
|
-
partition: 'Default',
|
|
72
|
-
payload: { test: 'message 1' }
|
|
73
|
-
}]
|
|
74
|
-
});
|
|
75
|
-
log('Push to Default partition succeeded', 'success');
|
|
76
|
-
|
|
77
|
-
// Test 4: Push to new partition (should create partition on-demand)
|
|
78
|
-
log('\nTest 4: Pushing to new partition (should create on-demand)...');
|
|
79
|
-
const pushResult2 = await client.push({
|
|
80
|
-
items: [{
|
|
81
|
-
queue: TEST_QUEUE,
|
|
82
|
-
partition: 'NewPartition',
|
|
83
|
-
payload: { test: 'message 2' }
|
|
84
|
-
}]
|
|
85
|
-
});
|
|
86
|
-
log('Push to NewPartition succeeded (partition created on-demand)', 'success');
|
|
87
|
-
|
|
88
|
-
// Test 5: Verify messages can be popped
|
|
89
|
-
log('\nTest 5: Verifying messages can be popped...');
|
|
90
|
-
const popResult = await client.pop({
|
|
91
|
-
queue: TEST_QUEUE,
|
|
92
|
-
batch: 10,
|
|
93
|
-
wait: false
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
if (popResult.messages && popResult.messages.length === 2) {
|
|
97
|
-
log(`Successfully retrieved ${popResult.messages.length} messages`, 'success');
|
|
98
|
-
|
|
99
|
-
// Check partitions
|
|
100
|
-
const partitions = new Set(popResult.messages.map(m => m.partition));
|
|
101
|
-
if (partitions.has('Default') && partitions.has('NewPartition')) {
|
|
102
|
-
log('Both partitions (Default and NewPartition) confirmed', 'success');
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Acknowledge messages
|
|
106
|
-
for (const msg of popResult.messages) {
|
|
107
|
-
await client.ack(msg.transactionId, 'completed');
|
|
108
|
-
}
|
|
109
|
-
log('Messages acknowledged', 'success');
|
|
110
|
-
} else {
|
|
111
|
-
log(`Expected 2 messages, got ${popResult.messages?.length || 0}`, 'error');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Test 6: Clean up
|
|
115
|
-
log('\nTest 6: Cleaning up...');
|
|
116
|
-
await client.queues.clear(TEST_QUEUE);
|
|
117
|
-
log('Test queue cleared', 'success');
|
|
118
|
-
|
|
119
|
-
console.log('\n' + '=' .repeat(80));
|
|
120
|
-
log('All tests passed! Queue creation policy working correctly', 'success');
|
|
121
|
-
console.log('=' .repeat(80));
|
|
122
|
-
|
|
123
|
-
console.log('\nSummary:');
|
|
124
|
-
console.log('✅ Queues must be created via configure endpoint');
|
|
125
|
-
console.log('✅ Push to non-existent queue fails with clear error');
|
|
126
|
-
console.log('✅ Partitions can still be created on-demand');
|
|
127
|
-
console.log('✅ No implicit queue creation during push operations');
|
|
128
|
-
|
|
129
|
-
} catch (error) {
|
|
130
|
-
log(`Test failed: ${error.message}`, 'error');
|
|
131
|
-
console.error(error);
|
|
132
|
-
process.exit(1);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Run the tests
|
|
137
|
-
runTests().catch(console.error);
|
package/examples/test-traceid.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Test client-provided traceId functionality
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { Queen } from '../src/client/client.js';
|
|
8
|
-
import crypto from 'crypto';
|
|
9
|
-
|
|
10
|
-
// Helper to generate a valid UUID v4
|
|
11
|
-
function generateUUID() {
|
|
12
|
-
return crypto.randomUUID();
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async function main() {
|
|
16
|
-
console.log('🧪 Testing Client-Provided TraceId\n');
|
|
17
|
-
|
|
18
|
-
const client = new Queen({
|
|
19
|
-
baseUrls: ['http://localhost:6632'],
|
|
20
|
-
timeout: 30000
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
// Configure test queue
|
|
25
|
-
await client.queue('trace-test', {
|
|
26
|
-
leaseTime: 300,
|
|
27
|
-
retryLimit: 3
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
// Test 1: Push with valid UUID traceId
|
|
31
|
-
console.log('1️⃣ Testing valid UUID traceId...');
|
|
32
|
-
const validTraceId = generateUUID();
|
|
33
|
-
console.log(` Generated UUID: ${validTraceId}`);
|
|
34
|
-
|
|
35
|
-
await client.push('trace-test', {
|
|
36
|
-
message: 'Test with valid traceId'
|
|
37
|
-
}, {
|
|
38
|
-
transactionId: 'txn-001',
|
|
39
|
-
traceId: validTraceId
|
|
40
|
-
});
|
|
41
|
-
console.log('✅ Message pushed with valid traceId\n');
|
|
42
|
-
|
|
43
|
-
// Test 2: Push with invalid traceId (should be ignored)
|
|
44
|
-
console.log('2️⃣ Testing invalid traceId (should be ignored)...');
|
|
45
|
-
const invalidTraceId = 'not-a-valid-uuid';
|
|
46
|
-
console.log(` Invalid traceId: ${invalidTraceId}`);
|
|
47
|
-
|
|
48
|
-
await client.push('trace-test', {
|
|
49
|
-
message: 'Test with invalid traceId'
|
|
50
|
-
}, {
|
|
51
|
-
transactionId: 'txn-002',
|
|
52
|
-
traceId: invalidTraceId // Will be ignored, server will generate one
|
|
53
|
-
});
|
|
54
|
-
console.log('✅ Message pushed (invalid traceId ignored)\n');
|
|
55
|
-
|
|
56
|
-
// Test 3: Push without traceId (server generates)
|
|
57
|
-
console.log('3️⃣ Testing without traceId (server generates)...');
|
|
58
|
-
await client.push('trace-test', {
|
|
59
|
-
message: 'Test without traceId'
|
|
60
|
-
}, {
|
|
61
|
-
transactionId: 'txn-003'
|
|
62
|
-
});
|
|
63
|
-
console.log('✅ Message pushed (server generated traceId)\n');
|
|
64
|
-
|
|
65
|
-
// Test 4: Using special properties format
|
|
66
|
-
console.log('4️⃣ Testing special properties format...');
|
|
67
|
-
const anotherValidTraceId = generateUUID();
|
|
68
|
-
|
|
69
|
-
await client.push('trace-test', {
|
|
70
|
-
_payload: { message: 'Special format test' },
|
|
71
|
-
_transactionId: 'txn-004',
|
|
72
|
-
_traceId: anotherValidTraceId
|
|
73
|
-
});
|
|
74
|
-
console.log('✅ Message pushed with special format\n');
|
|
75
|
-
|
|
76
|
-
// Test 5: Batch with mixed traceIds
|
|
77
|
-
console.log('5️⃣ Testing batch with mixed traceIds...');
|
|
78
|
-
const batchTraceId1 = generateUUID();
|
|
79
|
-
const batchTraceId2 = generateUUID();
|
|
80
|
-
|
|
81
|
-
await client.push('trace-test', [
|
|
82
|
-
{
|
|
83
|
-
message: 'Batch message 1',
|
|
84
|
-
transactionId: 'batch-001',
|
|
85
|
-
traceId: batchTraceId1 // Valid UUID
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
message: 'Batch message 2',
|
|
89
|
-
transactionId: 'batch-002',
|
|
90
|
-
traceId: 'invalid-trace' // Invalid, will be ignored
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
message: 'Batch message 3',
|
|
94
|
-
transactionId: 'batch-003'
|
|
95
|
-
// No traceId, server will generate
|
|
96
|
-
}
|
|
97
|
-
]);
|
|
98
|
-
console.log('✅ Batch pushed with mixed traceId scenarios\n');
|
|
99
|
-
|
|
100
|
-
// Retrieve and display messages
|
|
101
|
-
console.log('📥 Retrieving messages to verify traceIds...\n');
|
|
102
|
-
let count = 0;
|
|
103
|
-
for await (const msg of client.take('trace-test', { limit: 7 })) {
|
|
104
|
-
count++;
|
|
105
|
-
console.log(`Message ${count}:`);
|
|
106
|
-
console.log(` Transaction ID: ${msg.transactionId}`);
|
|
107
|
-
console.log(` Trace ID: ${msg.traceId}`);
|
|
108
|
-
console.log(` Data: ${JSON.stringify(msg.data)}`);
|
|
109
|
-
|
|
110
|
-
// Check if our valid traceIds were preserved
|
|
111
|
-
if (msg.transactionId === 'txn-001') {
|
|
112
|
-
if (msg.traceId === validTraceId) {
|
|
113
|
-
console.log(' ✅ Client-provided traceId was preserved!');
|
|
114
|
-
} else {
|
|
115
|
-
console.log(' ❌ Client-provided traceId was not preserved');
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (msg.transactionId === 'txn-002') {
|
|
120
|
-
if (msg.traceId !== invalidTraceId) {
|
|
121
|
-
console.log(' ✅ Invalid traceId was correctly replaced');
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
await client.ack(msg);
|
|
126
|
-
console.log('');
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
console.log('🎉 TraceId test completed successfully!');
|
|
130
|
-
console.log('\nSummary:');
|
|
131
|
-
console.log('- Valid UUID traceIds are accepted and preserved');
|
|
132
|
-
console.log('- Invalid traceIds are ignored (server generates new ones)');
|
|
133
|
-
console.log('- Missing traceIds are auto-generated by server');
|
|
134
|
-
|
|
135
|
-
} catch (error) {
|
|
136
|
-
console.error('❌ Test failed:', error.message);
|
|
137
|
-
process.exit(1);
|
|
138
|
-
} finally {
|
|
139
|
-
await client.close();
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Run test
|
|
144
|
-
main().catch(error => {
|
|
145
|
-
console.error('Fatal error:', error);
|
|
146
|
-
process.exit(1);
|
|
147
|
-
});
|
package/server.log
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
zsh: command not found: node
|
package/test-keepalive-v2.sh
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Better connection monitoring for macOS
|
|
4
|
-
echo "Monitoring HTTP connections to Queen servers..."
|
|
5
|
-
echo "Press Ctrl+C to stop"
|
|
6
|
-
echo ""
|
|
7
|
-
|
|
8
|
-
while true; do
|
|
9
|
-
# Use lsof instead of netstat for more reliable results on macOS
|
|
10
|
-
CONN_6632=$(lsof -nP -iTCP:6632 -sTCP:ESTABLISHED 2>/dev/null | grep -v COMMAND | wc -l | tr -d ' ')
|
|
11
|
-
CONN_6633=$(lsof -nP -iTCP:6633 -sTCP:ESTABLISHED 2>/dev/null | grep -v COMMAND | wc -l | tr -d ' ')
|
|
12
|
-
|
|
13
|
-
# Also check all states to see if connections exist at all
|
|
14
|
-
ALL_6632=$(lsof -nP -iTCP:6632 2>/dev/null | grep -v COMMAND | wc -l | tr -d ' ')
|
|
15
|
-
ALL_6633=$(lsof -nP -iTCP:6633 2>/dev/null | grep -v COMMAND | wc -l | tr -d ' ')
|
|
16
|
-
|
|
17
|
-
# Clear line and print
|
|
18
|
-
echo -ne "\r[6632] EST: $CONN_6632 (Total: $ALL_6632) | [6633] EST: $CONN_6633 (Total: $ALL_6633) "
|
|
19
|
-
|
|
20
|
-
sleep 0.5 # Check twice per second
|
|
21
|
-
done
|
|
22
|
-
|