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.
Files changed (135) hide show
  1. package/README.md +467 -1775
  2. package/package.json +12 -14
  3. package/src/client/client.js +664 -5
  4. package/src/managers/queueManagerOptimized.js +250 -47
  5. package/src/routes/ack.js +3 -3
  6. package/src/server.js +131 -3
  7. package/src/test/advanced-client-tests.js +761 -0
  8. package/src/test/advanced-pattern-tests.js +2 -2
  9. package/src/test/bus-mode-tests.js +6 -6
  10. package/src/test/core-tests.js +1 -1
  11. package/src/test/edge-case-tests.js +2 -2
  12. package/src/test/test-new.js +36 -1
  13. package/src/webapp-dist/assets/Analytics-DJrE4Rz2.css +1 -0
  14. package/src/webapp-dist/assets/Analytics-HEMXKmfJ.js +1 -0
  15. package/src/webapp-dist/assets/ConfirmDialog-YEoCdE7x.js +1 -0
  16. package/src/webapp-dist/assets/ConsumerGroups-CC5VJywp.css +1 -0
  17. package/src/webapp-dist/assets/ConsumerGroups-D8Z20HhZ.js +1 -0
  18. package/src/webapp-dist/assets/Dashboard-BRFOz6it.css +1 -0
  19. package/src/webapp-dist/assets/Dashboard-Bpx9I32h.js +1 -0
  20. package/src/webapp-dist/assets/LoadingSpinner-BPttXcbs.js +1 -0
  21. package/src/webapp-dist/assets/Messages-BOfVHKma.css +1 -0
  22. package/src/webapp-dist/assets/Messages-EKURCbLl.js +1 -0
  23. package/src/webapp-dist/assets/QueueDetail-BXXA7xoZ.css +1 -0
  24. package/src/webapp-dist/assets/QueueDetail-Bmxg0KiA.js +1 -0
  25. package/src/webapp-dist/assets/Queues-CvrJkrZT.css +1 -0
  26. package/src/webapp-dist/assets/Queues-yUx9_3-9.js +1 -0
  27. package/src/webapp-dist/assets/StatusBadge-C1bBtXHh.css +1 -0
  28. package/src/webapp-dist/assets/StatusBadge-C6N84XmO.js +1 -0
  29. package/src/webapp-dist/assets/analytics-BapTekLM.js +1 -0
  30. package/src/webapp-dist/assets/colors-5z6Q_kUr.js +18 -0
  31. package/src/webapp-dist/assets/index-B7w2bKT6.css +1 -0
  32. package/src/webapp-dist/assets/index-CUSnwYTH.js +31 -0
  33. package/src/webapp-dist/assets/messages-CRV6E-xU.js +1 -0
  34. package/src/webapp-dist/assets/queues-BdUbxfBC.js +1 -0
  35. package/src/webapp-dist/assets/resources-Bs9U-ceF.js +1 -0
  36. package/{webapp → src/webapp-dist}/index.html +2 -1
  37. package/API.md +0 -1226
  38. package/AUTH.md +0 -2044
  39. package/CHANGELOG_STATIC_SERVING.md +0 -213
  40. package/DEPLOYMENT.md +0 -425
  41. package/PROGRAMMATIC_SERVER.md +0 -239
  42. package/WEBAPP.md +0 -1889
  43. package/assets/dashboard-01.png +0 -0
  44. package/assets/dashboard.png +0 -0
  45. package/examples/batch-processing.js +0 -58
  46. package/examples/bus-mode.js +0 -239
  47. package/examples/continuous-consumer-optimized.js +0 -215
  48. package/examples/continuous-consumer.js +0 -159
  49. package/examples/continuous-producer.js +0 -343
  50. package/examples/mixed-mode.js +0 -277
  51. package/examples/multi-server-test.js +0 -305
  52. package/examples/programmatic-server.js +0 -58
  53. package/examples/server-with-frontend.js +0 -46
  54. package/examples/single.js +0 -64
  55. package/examples/smartchat-dealyed.js +0 -42
  56. package/examples/smartchat.js +0 -52
  57. package/examples/test-cache-invalidation.js +0 -119
  58. package/examples/test-cache-multi-server.js +0 -245
  59. package/examples/test-complete-client.js +0 -260
  60. package/examples/test-connection-recovery.js +0 -66
  61. package/examples/test-dashboard-api.js +0 -200
  62. package/examples/test-minimal-client.js +0 -112
  63. package/examples/test-queue-creation-policy.js +0 -137
  64. package/examples/test-traceid.js +0 -147
  65. package/server.log +0 -1
  66. package/test-keepalive-v2.sh +0 -22
  67. package/webapp/COLOR_GUIDE.md +0 -118
  68. package/webapp/README.md +0 -143
  69. package/webapp/package-lock.json +0 -3184
  70. package/webapp/package.json +0 -25
  71. package/webapp/postcss.config.js +0 -7
  72. package/webapp/public/assets/queen-logo-blue.svg +0 -210
  73. package/webapp/public/assets/queen-logo-cyan.svg +0 -210
  74. package/webapp/public/assets/queen-logo-indigo.svg +0 -210
  75. package/webapp/public/assets/queen-logo-orange.svg +0 -210
  76. package/webapp/public/assets/queen-logo-pink.svg +0 -210
  77. package/webapp/public/assets/queen-logo-purple.svg +0 -210
  78. package/webapp/public/assets/queen-logo-rose.svg +0 -239
  79. package/webapp/public/assets/queen-logo.svg +0 -263
  80. package/webapp/src/App.vue +0 -19
  81. package/webapp/src/api/analytics.js +0 -10
  82. package/webapp/src/api/client.js +0 -34
  83. package/webapp/src/api/consumers.js +0 -52
  84. package/webapp/src/api/health.js +0 -7
  85. package/webapp/src/api/messages.js +0 -26
  86. package/webapp/src/api/queues.js +0 -14
  87. package/webapp/src/api/resources.js +0 -8
  88. package/webapp/src/assets/styles/main.css +0 -357
  89. package/webapp/src/components/analytics/AnalyticsFilters.vue +0 -87
  90. package/webapp/src/components/analytics/AnalyticsMetrics.vue +0 -57
  91. package/webapp/src/components/analytics/MessageDistributionChart.vue +0 -111
  92. package/webapp/src/components/analytics/MessageFlowChart.vue +0 -173
  93. package/webapp/src/components/analytics/TimeRangeSelector.vue +0 -27
  94. package/webapp/src/components/analytics/TopQueuesChart.vue +0 -132
  95. package/webapp/src/components/common/ConfirmDialog.vue +0 -56
  96. package/webapp/src/components/common/LoadingSpinner.vue +0 -6
  97. package/webapp/src/components/common/MetricCard.vue +0 -43
  98. package/webapp/src/components/common/StatusBadge.vue +0 -45
  99. package/webapp/src/components/dashboard/MessageStatusCard.vue +0 -50
  100. package/webapp/src/components/dashboard/PerformanceCard.vue +0 -38
  101. package/webapp/src/components/dashboard/ThroughputChart.vue +0 -182
  102. package/webapp/src/components/dashboard/TopQueuesTable.vue +0 -53
  103. package/webapp/src/components/layout/AppLayout.vue +0 -110
  104. package/webapp/src/components/layout/AppSidebar.vue +0 -304
  105. package/webapp/src/components/messages/MessageDetailPanel.vue +0 -242
  106. package/webapp/src/components/messages/MessageFilters.vue +0 -101
  107. package/webapp/src/components/queue-detail/PartitionList.vue +0 -79
  108. package/webapp/src/components/queue-detail/PushMessageModal.vue +0 -175
  109. package/webapp/src/components/queue-detail/QueueConfig.vue +0 -63
  110. package/webapp/src/components/queue-detail/QueueDetailHeader.vue +0 -53
  111. package/webapp/src/components/queue-detail/RecentMessages.vue +0 -76
  112. package/webapp/src/components/queues/CreateQueueModal.vue +0 -193
  113. package/webapp/src/components/queues/QueueFilters.vue +0 -90
  114. package/webapp/src/composables/useApi.js +0 -34
  115. package/webapp/src/composables/useTheme.js +0 -36
  116. package/webapp/src/main.js +0 -11
  117. package/webapp/src/router/index.js +0 -42
  118. package/webapp/src/utils/colors.js +0 -96
  119. package/webapp/src/utils/formatters.js +0 -49
  120. package/webapp/src/views/Analytics.vue +0 -377
  121. package/webapp/src/views/ConsumerGroups.vue +0 -433
  122. package/webapp/src/views/Dashboard.vue +0 -418
  123. package/webapp/src/views/Messages.vue +0 -363
  124. package/webapp/src/views/QueueDetail.vue +0 -582
  125. package/webapp/src/views/Queues.vue +0 -496
  126. package/webapp/tailwind.config.js +0 -25
  127. package/webapp/vite.config.js +0 -10
  128. /package/{assets → src/webapp-dist/assets}/queen-logo-blue.svg +0 -0
  129. /package/{assets → src/webapp-dist/assets}/queen-logo-cyan.svg +0 -0
  130. /package/{assets → src/webapp-dist/assets}/queen-logo-indigo.svg +0 -0
  131. /package/{assets → src/webapp-dist/assets}/queen-logo-orange.svg +0 -0
  132. /package/{assets → src/webapp-dist/assets}/queen-logo-pink.svg +0 -0
  133. /package/{assets → src/webapp-dist/assets}/queen-logo-purple.svg +0 -0
  134. /package/{assets → src/webapp-dist/assets}/queen-logo-rose.svg +0 -0
  135. /package/{assets → src/webapp-dist/assets}/queen-logo.svg +0 -0
@@ -1,305 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Multi-Server Load Balancing Test
5
- *
6
- * This script tests the Queen client with multiple servers using different
7
- * load balancing strategies (ROUND_ROBIN and SESSION).
8
- *
9
- * Usage:
10
- * 1. Start two Queen servers on different ports:
11
- * PORT=6632 node src/server.js
12
- * PORT=6633 node src/server.js
13
- *
14
- * 2. Run this test:
15
- * node examples/multi-server-test.js
16
- */
17
-
18
- import { createQueenClient, LoadBalancingStrategy } from '../src/client/index.js';
19
-
20
- const servers = [
21
- 'http://localhost:6632',
22
- 'http://localhost:6633'
23
- ];
24
-
25
- // Test configuration
26
- const TEST_QUEUE = 'multi-server-test';
27
- const TEST_NAMESPACE = 'load-balancing';
28
-
29
- // Helper to log with timestamp
30
- const log = (message, type = 'info') => {
31
- const timestamp = new Date().toISOString();
32
- const prefix = type === 'error' ? 'āŒ' : type === 'success' ? 'āœ…' : 'ā„¹ļø';
33
- console.log(`[${timestamp}] ${prefix} ${message}`);
34
- };
35
-
36
- // Test Round Robin strategy
37
- async function testRoundRobinStrategy() {
38
- log('Testing ROUND_ROBIN load balancing strategy', 'info');
39
-
40
- const client = createQueenClient({
41
- baseUrls: servers,
42
- loadBalancingStrategy: LoadBalancingStrategy.ROUND_ROBIN,
43
- enableFailover: true
44
- });
45
-
46
- // Configure the queue
47
- await client.configure({
48
- queue: TEST_QUEUE,
49
- namespace: TEST_NAMESPACE,
50
- task: 'round-robin-test',
51
- options: {
52
- maxRetries: 3,
53
- retryDelay: 1000
54
- }
55
- });
56
-
57
- // Push multiple messages to see round-robin distribution
58
- const messages = [];
59
- for (let i = 1; i <= 10; i++) {
60
- messages.push({
61
- queue: TEST_QUEUE,
62
- partition: 'Default',
63
- payload: {
64
- id: i,
65
- strategy: 'round-robin',
66
- timestamp: Date.now()
67
- }
68
- });
69
- }
70
-
71
- log(`Pushing ${messages.length} messages with ROUND_ROBIN strategy`);
72
- const pushResult = await client.push({ items: messages });
73
- log(`Pushed messages: ${JSON.stringify(pushResult)}`, 'success');
74
-
75
- // Get load balancer stats
76
- const stats = client.getLoadBalancerStats();
77
- log(`Load balancer stats: ${JSON.stringify(stats, null, 2)}`);
78
-
79
- // Pop messages to verify they were stored
80
- log('Popping messages to verify...');
81
- const popResult = await client.pop({
82
- queue: TEST_QUEUE,
83
- batch: 5,
84
- wait: false
85
- });
86
-
87
- if (popResult.messages && popResult.messages.length > 0) {
88
- log(`Retrieved ${popResult.messages.length} messages`, 'success');
89
-
90
- // Acknowledge messages
91
- for (const msg of popResult.messages) {
92
- await client.ack(msg.transactionId, 'completed');
93
- }
94
- log('Messages acknowledged', 'success');
95
- } else {
96
- log('No messages retrieved', 'warning');
97
- }
98
-
99
- return client;
100
- }
101
-
102
- // Test Session affinity strategy
103
- async function testSessionStrategy() {
104
- log('\nTesting SESSION load balancing strategy', 'info');
105
-
106
- const client = createQueenClient({
107
- baseUrls: servers,
108
- loadBalancingStrategy: LoadBalancingStrategy.SESSION,
109
- enableFailover: true
110
- });
111
-
112
- // Configure the queue
113
- await client.configure({
114
- queue: TEST_QUEUE,
115
- namespace: TEST_NAMESPACE,
116
- task: 'session-test',
117
- options: {
118
- maxRetries: 3,
119
- retryDelay: 1000
120
- }
121
- });
122
-
123
- // Push multiple messages - should all go to the same server
124
- const messages = [];
125
- for (let i = 1; i <= 10; i++) {
126
- messages.push({
127
- queue: TEST_QUEUE,
128
- partition: 'Session',
129
- payload: {
130
- id: i,
131
- strategy: 'session',
132
- timestamp: Date.now()
133
- }
134
- });
135
- }
136
-
137
- log(`Pushing ${messages.length} messages with SESSION strategy`);
138
- const pushResult = await client.push({ items: messages });
139
- log(`Pushed messages: ${JSON.stringify(pushResult)}`, 'success');
140
-
141
- // Get load balancer stats
142
- const stats = client.getLoadBalancerStats();
143
- log(`Load balancer stats: ${JSON.stringify(stats, null, 2)}`);
144
-
145
- // Pop messages to verify they were stored
146
- log('Popping messages to verify...');
147
- const popResult = await client.pop({
148
- queue: TEST_QUEUE,
149
- partition: 'Session',
150
- batch: 5,
151
- wait: false
152
- });
153
-
154
- if (popResult.messages && popResult.messages.length > 0) {
155
- log(`Retrieved ${popResult.messages.length} messages from session-affinity server`, 'success');
156
-
157
- // Acknowledge messages
158
- for (const msg of popResult.messages) {
159
- await client.ack(msg.transactionId, 'completed');
160
- }
161
- log('Messages acknowledged', 'success');
162
- } else {
163
- log('No messages retrieved', 'warning');
164
- }
165
-
166
- return client;
167
- }
168
-
169
- // Test failover behavior
170
- async function testFailover() {
171
- log('\nTesting failover behavior (requires one server to be down)', 'info');
172
-
173
- const client = createQueenClient({
174
- baseUrls: [
175
- 'http://localhost:9999', // Non-existent server
176
- 'http://localhost:6632' // Working server
177
- ],
178
- loadBalancingStrategy: LoadBalancingStrategy.ROUND_ROBIN,
179
- enableFailover: true,
180
- timeout: 5000 // Shorter timeout for testing
181
- });
182
-
183
- try {
184
- // Try to push a message - should failover to working server
185
- log('Attempting to push message with one server down...');
186
- const result = await client.push({
187
- items: [{
188
- queue: TEST_QUEUE,
189
- partition: 'Failover',
190
- payload: { test: 'failover', timestamp: Date.now() }
191
- }]
192
- });
193
-
194
- log('Message pushed successfully via failover!', 'success');
195
- log(`Result: ${JSON.stringify(result)}`);
196
-
197
- // Get stats to see which server was used
198
- const stats = client.getLoadBalancerStats();
199
- log(`Load balancer stats after failover: ${JSON.stringify(stats, null, 2)}`);
200
-
201
- } catch (error) {
202
- log(`Failover test failed: ${error.message}`, 'error');
203
- }
204
-
205
- return client;
206
- }
207
-
208
- // Test WebSocket connections with multiple servers
209
- async function testWebSocketConnections() {
210
- log('\nTesting WebSocket connections with multiple servers', 'info');
211
-
212
- const client = createQueenClient({
213
- baseUrls: servers,
214
- loadBalancingStrategy: LoadBalancingStrategy.ROUND_ROBIN
215
- });
216
-
217
- // Create WebSocket connections to different servers
218
- log('Creating WebSocket connections...');
219
-
220
- const ws1 = client.createWebSocketConnection('/ws/dashboard');
221
- log(`WebSocket 1 connected to: ${ws1.serverUrl}`);
222
-
223
- const ws2 = client.createWebSocketConnection('/ws/dashboard');
224
- log(`WebSocket 2 connected to: ${ws2.serverUrl}`);
225
-
226
- // Set up message handlers
227
- ws1.onMessage((data) => {
228
- log(`WS1 received: ${JSON.stringify(data)}`);
229
- });
230
-
231
- ws2.onMessage((data) => {
232
- log(`WS2 received: ${JSON.stringify(data)}`);
233
- });
234
-
235
- // Keep connections open for a bit
236
- await new Promise(resolve => setTimeout(resolve, 2000));
237
-
238
- // Close connections
239
- ws1.close();
240
- ws2.close();
241
- log('WebSocket connections closed', 'success');
242
-
243
- return client;
244
- }
245
-
246
- // Test single server backward compatibility
247
- async function testBackwardCompatibility() {
248
- log('\nTesting backward compatibility with single baseUrl', 'info');
249
-
250
- // Old style - single baseUrl
251
- const client = createQueenClient({
252
- baseUrl: 'http://localhost:6632',
253
- timeout: 30000
254
- });
255
-
256
- try {
257
- const result = await client.push({
258
- items: [{
259
- queue: TEST_QUEUE,
260
- partition: 'Compatibility',
261
- payload: { test: 'backward-compatibility', timestamp: Date.now() }
262
- }]
263
- });
264
-
265
- log('Backward compatibility test passed!', 'success');
266
- log(`Result: ${JSON.stringify(result)}`);
267
-
268
- // This should return null for single-server mode
269
- const stats = client.getLoadBalancerStats();
270
- log(`Load balancer stats (should be null): ${stats}`);
271
-
272
- } catch (error) {
273
- log(`Backward compatibility test failed: ${error.message}`, 'error');
274
- }
275
-
276
- return client;
277
- }
278
-
279
- // Main test runner
280
- async function runTests() {
281
- console.log('=' .repeat(80));
282
- console.log('Queen Multi-Server Load Balancing Test Suite');
283
- console.log('=' .repeat(80));
284
-
285
- try {
286
- // Test different strategies
287
- await testRoundRobinStrategy();
288
- await testSessionStrategy();
289
- await testFailover();
290
- await testWebSocketConnections();
291
- await testBackwardCompatibility();
292
-
293
- console.log('\n' + '=' .repeat(80));
294
- log('All tests completed!', 'success');
295
- console.log('=' .repeat(80));
296
-
297
- } catch (error) {
298
- log(`Test suite failed: ${error.message}`, 'error');
299
- console.error(error);
300
- process.exit(1);
301
- }
302
- }
303
-
304
- // Run the tests
305
- runTests().catch(console.error);
@@ -1,58 +0,0 @@
1
- /**
2
- * Example: Starting Queen Server Programmatically
3
- *
4
- * This example shows how to import and run the Queen server
5
- * directly from your code, rather than running it as a separate process.
6
- */
7
-
8
- import { QueenServer, Queen } from 'queen-mq';
9
-
10
- // Start the server programmatically
11
- console.log('Starting Queen Server...');
12
-
13
- const server = await QueenServer({
14
- port: 3000,
15
- host: '127.0.0.1'
16
- });
17
-
18
- console.log(`āœ… Server started at http://${server.host}:${server.port}`);
19
-
20
- // Now you can use the client in the same process
21
- const client = new Queen({
22
- servers: [`http://${server.host}:${server.port}`]
23
- });
24
-
25
- // Create a queue
26
- await client.push({
27
- queue: 'example-queue',
28
- items: [
29
- { data: { message: 'Hello from programmatic server!' } }
30
- ]
31
- });
32
-
33
- console.log('āœ… Message pushed to queue');
34
-
35
- // Pop a message
36
- const result = await client.pop({
37
- queue: 'example-queue'
38
- });
39
-
40
- console.log('āœ… Message received:', result.messages[0]?.data);
41
-
42
- // Acknowledge the message
43
- if (result.messages.length > 0) {
44
- await client.ack({
45
- transactionId: result.messages[0].transactionId,
46
- status: 'completed'
47
- });
48
- console.log('āœ… Message acknowledged');
49
- }
50
-
51
- // Graceful shutdown on SIGINT
52
- process.on('SIGINT', async () => {
53
- console.log('\nShutting down...');
54
- await server.shutdown('SIGINT');
55
- });
56
-
57
- console.log('\nšŸ“ Server is running. Press Ctrl+C to stop.');
58
-
@@ -1,46 +0,0 @@
1
- /**
2
- * Example: Starting Queen Server with Built-in Frontend Dashboard
3
- *
4
- * This example shows how to run Queen with the frontend dashboard
5
- * served from the same server (single deployment unit).
6
- *
7
- * Prerequisites:
8
- * - Build the frontend first: cd webapp && npm run build
9
- */
10
-
11
- import { QueenServer } from '../src/server.js';
12
-
13
- console.log('Starting Queen Server with Frontend Dashboard...\n');
14
-
15
- const server = await QueenServer({
16
- port: 3000,
17
- host: '127.0.0.1',
18
- serveWebapp: true // šŸ‘ˆ Enable frontend serving
19
- });
20
-
21
- console.log('\nāœ… Server started successfully!');
22
- console.log(`
23
- šŸ“Š Access Points:
24
- - Frontend Dashboard: http://${server.host}:${server.port}/
25
- - API Endpoint: http://${server.host}:${server.port}/api/v1/
26
- - Health Check: http://${server.host}:${server.port}/health
27
- - Metrics: http://${server.host}:${server.port}/metrics
28
-
29
- šŸŽÆ Single Port Deployment:
30
- Everything (frontend + API) served from port ${server.port}!
31
- No CORS issues, no separate static file server needed.
32
-
33
- šŸ“ To test:
34
- 1. Open http://${server.host}:${server.port}/ in your browser
35
- 2. You should see the Queen Dashboard UI
36
- 3. All API calls will work from the same origin
37
-
38
- Press Ctrl+C to stop.
39
- `);
40
-
41
- // Graceful shutdown
42
- process.on('SIGINT', async () => {
43
- console.log('\n\nShutting down...');
44
- await server.shutdown('SIGINT');
45
- });
46
-
@@ -1,64 +0,0 @@
1
- import { createQueenClient } from '../src/client/index.js';
2
-
3
- const client = createQueenClient({
4
- baseUrl: process.env.QUEEN_URL || 'http://localhost:6632',
5
- timeout: 10000 // 10 second timeout for operations
6
- });
7
-
8
- // V2: Using queue and partition structure
9
- const queue = 'smartchat-agent';
10
- const partition = 'id-1'; // Can use partition to separate different agents
11
-
12
- async function consumer () {
13
- // Start consuming messages from the specific partition
14
- const stop = client.consume({
15
- queue: queue,
16
- partition: partition, // Optional: remove to consume from any partition
17
- handler: async (message) => {
18
- console.log(`Consumed message from ${message.partition}: ${message.data.data}`);
19
- },
20
- options: {
21
- wait: true,
22
- timeout: 10000
23
- }
24
- });
25
-
26
- // Return stop function for cleanup if needed
27
- return stop;
28
- }
29
-
30
- let count = 0;
31
- async function producer () {
32
- const messages = [{
33
- queue: queue,
34
- partition: partition, // Optional: defaults to "Default"
35
- payload: {
36
- id: count,
37
- data: `Hello, world! ${count++}`,
38
- timestamp: new Date().toISOString()
39
- }
40
- }];
41
-
42
- const result = await client.push({
43
- items: messages
44
- });
45
- console.log(`Pushed ${result.messages.length} messages to ${queue}/${partition}`);
46
- }
47
-
48
- // Start consumer
49
- consumer().then(stop => {
50
- // Handle graceful shutdown
51
- process.on('SIGINT', () => {
52
- console.log('\nStopping consumer...');
53
- stop();
54
- process.exit(0);
55
- });
56
- });
57
-
58
- // Start producer loop
59
- (async () => {
60
- while (true) {
61
- await producer();
62
- await new Promise(resolve => setTimeout(resolve, 10000));
63
- }
64
- })();
@@ -1,42 +0,0 @@
1
- // Create client
2
- import fs from 'fs';
3
- import { createQueenClient } from '../src/client/index.js';
4
-
5
- const client = createQueenClient({
6
- baseUrl: 'http://localhost:6632'
7
- });
8
-
9
- // Configure a queue with delayed processing
10
- await client.configure({
11
- queue: 'htmls-delayed-02',
12
- // partition parameter removed - all config is queue-level now
13
- options: {
14
- windowBuffer: 10,
15
- //delayedProcessing: 10, // Don't process messages until 60 seconds old
16
- leaseTime: 300,
17
- retryLimit: 3
18
- }
19
- })
20
-
21
- for (let i = 0; i < 10; i++) {
22
- await client.push({
23
- items: [{
24
- queue: 'htmls-delayed-02',
25
- partition: 'html-02', // Use 'Default' instead of 0
26
- payload: { to: 'user-' + i + '@example.com' },
27
- }]
28
- })
29
- }
30
-
31
- const stop = await client.consume({
32
- queue: 'htmls-delayed-02',
33
- partition: 'html-02', // Use 'Default' instead of 0
34
- handler: async (message) => {
35
- console.log(message)
36
- },
37
- options: {
38
- wait: true,
39
- timeout: 30000,
40
- batch: 5
41
- }
42
- })
@@ -1,52 +0,0 @@
1
- // Create client
2
- import fs from 'fs';
3
- import { createQueenClient } from '../src/client/index.js';
4
-
5
- const client = createQueenClient({
6
- baseUrl: 'http://localhost:6632'
7
- });
8
-
9
- const numberOfConsumers = 10
10
-
11
- async function producer () {
12
- let count = 0;
13
- while (true) {
14
- const partition = count % 2;
15
- console.log('Producing to partition:', partition);
16
- const items = [];
17
- for (let i = 0; i < 100; i++) {
18
- items.push({ queue: 'htmls', partition: partition, payload: { to: 'user@example.com-' + count++ } });
19
- }
20
- await client.push({
21
- items: items
22
- })
23
- await new Promise(resolve => setTimeout(resolve, 50));
24
- }
25
- }
26
-
27
- async function consumer (i) {
28
- const stop = client.consume({
29
- queue: 'htmls',
30
- consumerGroup: 'smartchat-' + i,
31
- handler: async (message) => {
32
- console.log(i, 'Processing:', message.data);
33
- //fs.appendFileSync('consumed_items ' + message.partition + '.json', JSON.stringify(message.data) + '\n');
34
- },
35
- options: {
36
- batch: 100, // Process up to 10 messages at a time
37
- wait: true, // Wait for messages if queue is empty
38
- timeout: 30000 // Timeout for long polling
39
- }
40
- });
41
-
42
- return stop;
43
- }
44
-
45
-
46
- if (process.argv[2] === 'producer') {
47
- producer();
48
- } else {
49
- for (let i = 0; i < numberOfConsumers; i++) {
50
- consumer(i);
51
- }
52
- }
@@ -1,119 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Example: Cache Invalidation with System Events
4
- *
5
- * This example demonstrates how the system event propagation
6
- * ensures cache consistency across multiple server instances.
7
- */
8
-
9
- import { createQueenClient } from '../src/client/queenClient.js';
10
-
11
- // Simulate two different server instances
12
- const server1 = createQueenClient({ baseUrl: 'http://localhost:6632' });
13
- const server2 = createQueenClient({ baseUrl: 'http://localhost:6633' }); // Would be a different port in production
14
-
15
- async function demonstrateCacheInvalidation() {
16
- console.log('šŸ“Š Demonstrating Cache Invalidation with System Events\n');
17
- console.log('=' .repeat(60));
18
-
19
- const queueName = 'cache-test-queue';
20
-
21
- try {
22
- // Step 1: Server 1 creates a queue
23
- console.log('\n1ļøāƒ£ Server 1 creates a queue with initial configuration:');
24
- await server1.configure({
25
- queue: queueName,
26
- options: {
27
- ttl: 300,
28
- retryLimit: 3,
29
- priority: 5
30
- }
31
- });
32
- console.log(' āœ… Queue created with TTL=300, retryLimit=3, priority=5');
33
-
34
- // Step 2: Both servers use the queue
35
- console.log('\n2ļøāƒ£ Both servers push messages to the queue:');
36
-
37
- await server1.push({
38
- queue: queueName,
39
- messages: [{ id: 'msg-from-server1', payload: { source: 'server1' } }]
40
- });
41
- console.log(' āœ… Server 1 pushed a message (uses cached config)');
42
-
43
- // In a real multi-server setup, server2 would have its own cache
44
- // For this demo, we're using the same server but the principle applies
45
- await server2.push({
46
- queue: queueName,
47
- messages: [{ id: 'msg-from-server2', payload: { source: 'server2' } }]
48
- });
49
- console.log(' āœ… Server 2 pushed a message (fetches and caches config)');
50
-
51
- // Step 3: Server 1 updates the queue configuration
52
- console.log('\n3ļøāƒ£ Server 1 updates queue configuration:');
53
- await server1.configure({
54
- queue: queueName,
55
- options: {
56
- ttl: 600, // Changed from 300
57
- retryLimit: 5, // Changed from 3
58
- priority: 10 // Changed from 5
59
- }
60
- });
61
- console.log(' āœ… Configuration updated: TTL=600, retryLimit=5, priority=10');
62
- console.log(' šŸ“Ø System event emitted to propagate changes');
63
-
64
- // Step 4: Wait a moment for event propagation
65
- console.log('\n4ļøāƒ£ Waiting for system event propagation...');
66
- await new Promise(resolve => setTimeout(resolve, 100));
67
-
68
- // Step 5: Both servers use the queue again
69
- console.log('\n5ļøāƒ£ Both servers push messages again:');
70
-
71
- await server1.push({
72
- queue: queueName,
73
- messages: [{ id: 'msg2-from-server1', payload: { after: 'update' } }]
74
- });
75
- console.log(' āœ… Server 1 uses new config (immediate local update)');
76
-
77
- await server2.push({
78
- queue: queueName,
79
- messages: [{ id: 'msg2-from-server2', payload: { after: 'update' } }]
80
- });
81
- console.log(' āœ… Server 2 uses new config (cache invalidated by event)');
82
-
83
- // Step 6: Verify the queue stats
84
- console.log('\n6ļøāƒ£ Verifying queue statistics:');
85
- const stats = await server1.getQueueStats(queueName);
86
- console.log(` šŸ“Š Total messages: ${stats.total}`);
87
- console.log(` šŸ“Š Pending: ${stats.pending}`);
88
-
89
- // Step 7: Check system events queue
90
- console.log('\n7ļøāƒ£ Checking system events queue:');
91
- try {
92
- const systemStats = await server1.getQueueStats('__system_events__');
93
- console.log(` šŸ“Š System events processed: ${systemStats.completed || 0}`);
94
- console.log(` šŸ“Š System events pending: ${systemStats.pending || 0}`);
95
- } catch (error) {
96
- console.log(' ā„¹ļø System queue may not have stats if events were already consumed');
97
- }
98
-
99
- console.log('\n' + '=' .repeat(60));
100
- console.log('✨ Cache invalidation demonstration completed!');
101
- console.log('\nšŸ’” Key Points:');
102
- console.log(' • Configuration changes trigger system events');
103
- console.log(' • Events are propagated to all server instances');
104
- console.log(' • Each server invalidates its cache upon receiving events');
105
- console.log(' • This ensures consistency across the cluster');
106
-
107
- } catch (error) {
108
- console.error('āŒ Error:', error.message);
109
- process.exit(1);
110
- }
111
- }
112
-
113
- // Run the demonstration
114
- demonstrateCacheInvalidation().then(() => {
115
- process.exit(0);
116
- }).catch(error => {
117
- console.error('Fatal error:', error);
118
- process.exit(1);
119
- });