queen-mq 0.12.0 → 0.12.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/client-v2/Queen.js +5 -3
- package/client-v2/builders/TransactionBuilder.js +11 -4
- package/client-v2/http/HttpClient.js +7 -2
- package/client-v2/utils/defaults.js +2 -1
- package/package.json +1 -1
- package/test-v2/bootstrap.js +316 -0
- package/test-v2/run.js +4 -15
- package/test-v2/transaction.js +66 -0
- package/test-v2/AI_TEST_SUMMARY.md +0 -226
- package/test-v2/GETTING_STARTED.md +0 -181
- package/test-v2/MAINTENANCE_TEST.md +0 -148
- package/test-v2/README_SUBSCRIPTION_TESTS.md +0 -201
- package/test-v2/ai_buffering.js +0 -194
- package/test-v2/ai_error_handling.js +0 -223
- package/test-v2/ai_lease_renewal.js +0 -206
- package/test-v2/ai_mixed_scenarios.js +0 -278
- package/test-v2/ai_priority.js +0 -169
- package/test-v2/ai_resources.js +0 -217
- package/test-v2/ai_ttl_retention.js +0 -170
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Lease Renewal Tests
|
|
3
|
-
* Tests manual lease extension functionality
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export async function testManualLeaseRenewal(client) {
|
|
7
|
-
const queue = await client.queue('test-queue-v2-manual-renewal')
|
|
8
|
-
.config({ leaseTime: 2 })
|
|
9
|
-
.create()
|
|
10
|
-
|
|
11
|
-
if (!queue.configured) {
|
|
12
|
-
return { success: false, message: 'Queue not created' }
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
await client.queue('test-queue-v2-manual-renewal')
|
|
16
|
-
.push([{ data: { test: 'renewal' } }])
|
|
17
|
-
|
|
18
|
-
const messages = await client.queue('test-queue-v2-manual-renewal')
|
|
19
|
-
.batch(1)
|
|
20
|
-
.wait(false)
|
|
21
|
-
.pop()
|
|
22
|
-
|
|
23
|
-
if (messages.length === 0) {
|
|
24
|
-
return { success: false, message: 'No message to test' }
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const message = messages[0]
|
|
28
|
-
|
|
29
|
-
// Wait 1 second
|
|
30
|
-
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
31
|
-
|
|
32
|
-
// Renew the lease
|
|
33
|
-
const renewResult = await client.renew(message)
|
|
34
|
-
|
|
35
|
-
if (!renewResult.success) {
|
|
36
|
-
return { success: false, message: 'Lease renewal failed' }
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Wait another 2 seconds (total 3 seconds, original lease was 2 seconds)
|
|
40
|
-
await new Promise(resolve => setTimeout(resolve, 2000))
|
|
41
|
-
|
|
42
|
-
// Try to ack - should succeed because we renewed
|
|
43
|
-
const ackResult = await client.ack(message, true)
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
success: ackResult.success === true,
|
|
47
|
-
message: 'Manual lease renewal works correctly'
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export async function testBatchLeaseRenewal(client) {
|
|
52
|
-
const queue = await client.queue('test-queue-v2-batch-renewal')
|
|
53
|
-
.config({ leaseTime: 2 })
|
|
54
|
-
.create()
|
|
55
|
-
|
|
56
|
-
if (!queue.configured) {
|
|
57
|
-
return { success: false, message: 'Queue not created' }
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
await client.queue('test-queue-v2-batch-renewal').push([
|
|
61
|
-
{ data: { id: 1 } },
|
|
62
|
-
{ data: { id: 2 } },
|
|
63
|
-
{ data: { id: 3 } }
|
|
64
|
-
])
|
|
65
|
-
|
|
66
|
-
const messages = await client.queue('test-queue-v2-batch-renewal')
|
|
67
|
-
.batch(3)
|
|
68
|
-
.wait(false)
|
|
69
|
-
.pop()
|
|
70
|
-
|
|
71
|
-
if (messages.length !== 3) {
|
|
72
|
-
return { success: false, message: 'Expected 3 messages' }
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Wait 1 second
|
|
76
|
-
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
77
|
-
|
|
78
|
-
// Renew all leases
|
|
79
|
-
const renewResults = await client.renew(messages)
|
|
80
|
-
|
|
81
|
-
const allSuccess = renewResults.every(r => r.success === true)
|
|
82
|
-
|
|
83
|
-
if (!allSuccess) {
|
|
84
|
-
return { success: false, message: 'Batch renewal failed' }
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Wait another 2 seconds
|
|
88
|
-
await new Promise(resolve => setTimeout(resolve, 2000))
|
|
89
|
-
|
|
90
|
-
// Try to ack all - should succeed
|
|
91
|
-
const ackResult = await client.ack(messages, true)
|
|
92
|
-
|
|
93
|
-
return {
|
|
94
|
-
success: ackResult.success === true,
|
|
95
|
-
message: 'Batch lease renewal works correctly'
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export async function testRenewalWithLeaseId(client) {
|
|
100
|
-
const queue = await client.queue('test-queue-v2-renewal-leaseid')
|
|
101
|
-
.config({ leaseTime: 2 })
|
|
102
|
-
.create()
|
|
103
|
-
|
|
104
|
-
if (!queue.configured) {
|
|
105
|
-
return { success: false, message: 'Queue not created' }
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
await client.queue('test-queue-v2-renewal-leaseid')
|
|
109
|
-
.push([{ data: { test: 'data' } }])
|
|
110
|
-
|
|
111
|
-
const messages = await client.queue('test-queue-v2-renewal-leaseid')
|
|
112
|
-
.batch(1)
|
|
113
|
-
.wait(false)
|
|
114
|
-
.pop()
|
|
115
|
-
|
|
116
|
-
if (messages.length === 0 || !messages[0].leaseId) {
|
|
117
|
-
return { success: false, message: 'No message or leaseId' }
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const leaseId = messages[0].leaseId
|
|
121
|
-
|
|
122
|
-
// Renew using just the leaseId string
|
|
123
|
-
const renewResult = await client.renew(leaseId)
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
success: renewResult.success === true,
|
|
127
|
-
message: 'Lease renewal with leaseId string works'
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export async function testRenewalOfExpiredLease(client) {
|
|
132
|
-
const queue = await client.queue('test-queue-v2-renewal-expired')
|
|
133
|
-
.config({ leaseTime: 1 })
|
|
134
|
-
.create()
|
|
135
|
-
|
|
136
|
-
if (!queue.configured) {
|
|
137
|
-
return { success: false, message: 'Queue not created' }
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
await client.queue('test-queue-v2-renewal-expired')
|
|
141
|
-
.push([{ data: { test: 'data' } }])
|
|
142
|
-
|
|
143
|
-
const messages = await client.queue('test-queue-v2-renewal-expired')
|
|
144
|
-
.batch(1)
|
|
145
|
-
.wait(false)
|
|
146
|
-
.pop()
|
|
147
|
-
|
|
148
|
-
if (messages.length === 0) {
|
|
149
|
-
return { success: false, message: 'No message to test' }
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Wait for lease to expire
|
|
153
|
-
await new Promise(resolve => setTimeout(resolve, 2000))
|
|
154
|
-
|
|
155
|
-
// Try to renew expired lease
|
|
156
|
-
const renewResult = await client.renew(messages[0])
|
|
157
|
-
|
|
158
|
-
// Should fail
|
|
159
|
-
return {
|
|
160
|
-
success: renewResult.success === false,
|
|
161
|
-
message: 'Expired lease renewal correctly rejected'
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export async function testMultipleRenewals(client) {
|
|
166
|
-
const queue = await client.queue('test-queue-v2-multiple-renewals')
|
|
167
|
-
.config({ leaseTime: 2 })
|
|
168
|
-
.create()
|
|
169
|
-
|
|
170
|
-
if (!queue.configured) {
|
|
171
|
-
return { success: false, message: 'Queue not created' }
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
await client.queue('test-queue-v2-multiple-renewals')
|
|
175
|
-
.push([{ data: { test: 'data' } }])
|
|
176
|
-
|
|
177
|
-
const messages = await client.queue('test-queue-v2-multiple-renewals')
|
|
178
|
-
.batch(1)
|
|
179
|
-
.wait(false)
|
|
180
|
-
.pop()
|
|
181
|
-
|
|
182
|
-
if (messages.length === 0) {
|
|
183
|
-
return { success: false, message: 'No message to test' }
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const message = messages[0]
|
|
187
|
-
|
|
188
|
-
// Renew multiple times
|
|
189
|
-
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
190
|
-
const renew1 = await client.renew(message)
|
|
191
|
-
|
|
192
|
-
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
193
|
-
const renew2 = await client.renew(message)
|
|
194
|
-
|
|
195
|
-
await new Promise(resolve => setTimeout(resolve, 1000))
|
|
196
|
-
const renew3 = await client.renew(message)
|
|
197
|
-
|
|
198
|
-
// After 3 seconds, ack should still work
|
|
199
|
-
const ackResult = await client.ack(message, true)
|
|
200
|
-
|
|
201
|
-
return {
|
|
202
|
-
success: renew1.success && renew2.success && renew3.success && ackResult.success,
|
|
203
|
-
message: 'Multiple lease renewals work correctly'
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Mixed Scenario Tests
|
|
3
|
-
* Complex tests combining multiple features
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export async function testMultipleQueuesSimultaneous(client) {
|
|
7
|
-
// Create multiple queues with different configurations
|
|
8
|
-
await client.queue('test-queue-v2-mixed-1')
|
|
9
|
-
.config({ priority: 1, leaseTime: 60 })
|
|
10
|
-
.create()
|
|
11
|
-
|
|
12
|
-
await client.queue('test-queue-v2-mixed-2')
|
|
13
|
-
.config({ priority: 5, retryLimit: 5 })
|
|
14
|
-
.create()
|
|
15
|
-
|
|
16
|
-
await client.queue('test-queue-v2-mixed-3')
|
|
17
|
-
.config({ priority: 10, delayedProcessing: 1 })
|
|
18
|
-
.create()
|
|
19
|
-
|
|
20
|
-
// Push to all queues
|
|
21
|
-
await Promise.all([
|
|
22
|
-
client.queue('test-queue-v2-mixed-1').push([{ data: { queue: 1 } }]),
|
|
23
|
-
client.queue('test-queue-v2-mixed-2').push([{ data: { queue: 2 } }]),
|
|
24
|
-
client.queue('test-queue-v2-mixed-3').push([{ data: { queue: 3 } }])
|
|
25
|
-
])
|
|
26
|
-
|
|
27
|
-
// Wait for delayed queue
|
|
28
|
-
await new Promise(resolve => setTimeout(resolve, 1500))
|
|
29
|
-
|
|
30
|
-
// Pop from all
|
|
31
|
-
const results = await Promise.all([
|
|
32
|
-
client.queue('test-queue-v2-mixed-1').batch(1).wait(false).pop(),
|
|
33
|
-
client.queue('test-queue-v2-mixed-2').batch(1).wait(false).pop(),
|
|
34
|
-
client.queue('test-queue-v2-mixed-3').batch(1).wait(false).pop()
|
|
35
|
-
])
|
|
36
|
-
|
|
37
|
-
const totalMessages = results.reduce((sum, msgs) => sum + msgs.length, 0)
|
|
38
|
-
|
|
39
|
-
return {
|
|
40
|
-
success: totalMessages === 3,
|
|
41
|
-
message: `Multiple queues working: ${totalMessages} messages`
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export async function testCrossQueueWorkflow(client) {
|
|
46
|
-
// Setup: 3-stage processing pipeline
|
|
47
|
-
await client.queue('test-queue-v2-workflow-stage1').create()
|
|
48
|
-
await client.queue('test-queue-v2-workflow-stage2').create()
|
|
49
|
-
await client.queue('test-queue-v2-workflow-stage3').create()
|
|
50
|
-
|
|
51
|
-
// Stage 1: Initial message
|
|
52
|
-
await client.queue('test-queue-v2-workflow-stage1')
|
|
53
|
-
.push([{ data: { stage: 1, value: 10 } }])
|
|
54
|
-
|
|
55
|
-
// Process stage 1 -> stage 2
|
|
56
|
-
const msg1 = await client.queue('test-queue-v2-workflow-stage1')
|
|
57
|
-
.batch(1).wait(false).pop()
|
|
58
|
-
|
|
59
|
-
if (msg1.length === 0) {
|
|
60
|
-
return { success: false, message: 'Stage 1 failed' }
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
await client.transaction()
|
|
64
|
-
.queue('test-queue-v2-workflow-stage2')
|
|
65
|
-
.push([{ data: { stage: 2, value: msg1[0].data.value * 2 } }])
|
|
66
|
-
.ack(msg1[0])
|
|
67
|
-
.commit()
|
|
68
|
-
|
|
69
|
-
// Process stage 2 -> stage 3
|
|
70
|
-
const msg2 = await client.queue('test-queue-v2-workflow-stage2')
|
|
71
|
-
.batch(1).wait(false).pop()
|
|
72
|
-
|
|
73
|
-
if (msg2.length === 0) {
|
|
74
|
-
return { success: false, message: 'Stage 2 failed' }
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
await client.transaction()
|
|
78
|
-
.queue('test-queue-v2-workflow-stage3')
|
|
79
|
-
.push([{ data: { stage: 3, value: msg2[0].data.value + 5 } }])
|
|
80
|
-
.ack(msg2[0])
|
|
81
|
-
.commit()
|
|
82
|
-
|
|
83
|
-
// Verify final result
|
|
84
|
-
const msg3 = await client.queue('test-queue-v2-workflow-stage3')
|
|
85
|
-
.batch(1).wait(false).pop()
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
success: msg3.length === 1 && msg3[0].data.value === 25,
|
|
89
|
-
message: `Cross-queue workflow completed: final value ${msg3[0]?.data.value}`
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export async function testPartitionWithConsumerGroupAndRetries(client) {
|
|
94
|
-
const queue = await client.queue('test-queue-v2-complex-partition')
|
|
95
|
-
.config({ retryLimit: 2 })
|
|
96
|
-
.create()
|
|
97
|
-
|
|
98
|
-
if (!queue.configured) {
|
|
99
|
-
return { success: false, message: 'Queue not created' }
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Push to specific partition
|
|
103
|
-
await client.queue('test-queue-v2-complex-partition')
|
|
104
|
-
.partition('complex-partition-1')
|
|
105
|
-
.push([{ data: { test: 'complex' } }])
|
|
106
|
-
|
|
107
|
-
let attemptCount = 0
|
|
108
|
-
|
|
109
|
-
// Consume with consumer group, fail first time
|
|
110
|
-
await client.queue('test-queue-v2-complex-partition')
|
|
111
|
-
.partition('complex-partition-1')
|
|
112
|
-
.group('complex-group')
|
|
113
|
-
.batch(1)
|
|
114
|
-
.wait(false)
|
|
115
|
-
.limit(2)
|
|
116
|
-
.each()
|
|
117
|
-
.consume(async (msg) => {
|
|
118
|
-
attemptCount++
|
|
119
|
-
if (attemptCount === 1) {
|
|
120
|
-
throw new Error('First attempt fails')
|
|
121
|
-
}
|
|
122
|
-
// Second attempt succeeds
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
return {
|
|
126
|
-
success: attemptCount === 2,
|
|
127
|
-
message: 'Complex partition/group/retry scenario works'
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export async function testBufferedPushWithTransactionConsume(client) {
|
|
132
|
-
await client.queue('test-queue-v2-buf-txn-source').create()
|
|
133
|
-
await client.queue('test-queue-v2-buf-txn-dest').create()
|
|
134
|
-
|
|
135
|
-
// Buffered push to source
|
|
136
|
-
for (let i = 0; i < 10; i++) {
|
|
137
|
-
await client.queue('test-queue-v2-buf-txn-source')
|
|
138
|
-
.buffer({ messageCount: 10, timeMillis: 2000 })
|
|
139
|
-
.push([{ data: { id: i } }])
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Wait for flush
|
|
143
|
-
await new Promise(resolve => setTimeout(resolve, 2500))
|
|
144
|
-
|
|
145
|
-
// Consume with transaction to move to destination
|
|
146
|
-
let processed = 0
|
|
147
|
-
await client.queue('test-queue-v2-buf-txn-source')
|
|
148
|
-
.batch(10)
|
|
149
|
-
.wait(false)
|
|
150
|
-
.limit(1)
|
|
151
|
-
.autoAck(false)
|
|
152
|
-
.consume(async (msgs) => {
|
|
153
|
-
for (const msg of msgs) {
|
|
154
|
-
await client.transaction()
|
|
155
|
-
.queue('test-queue-v2-buf-txn-dest')
|
|
156
|
-
.push([{ data: { processed: true, originalId: msg.data.id } }])
|
|
157
|
-
.ack(msg)
|
|
158
|
-
.commit()
|
|
159
|
-
processed++
|
|
160
|
-
}
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
// Verify destination
|
|
164
|
-
const destMsgs = await client.queue('test-queue-v2-buf-txn-dest')
|
|
165
|
-
.batch(20).wait(false).pop()
|
|
166
|
-
|
|
167
|
-
return {
|
|
168
|
-
success: processed === 10 && destMsgs.length === 10,
|
|
169
|
-
message: `Buffered push + transaction consume: ${destMsgs.length} messages`
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export async function testNamespaceWithMultipleQueues(client) {
|
|
174
|
-
const namespace = 'test-mixed-namespace'
|
|
175
|
-
|
|
176
|
-
// Create multiple queues in same namespace
|
|
177
|
-
await client.queue('test-queue-v2-ns-multi-a')
|
|
178
|
-
.namespace(namespace)
|
|
179
|
-
.config({ priority: 10 })
|
|
180
|
-
.create()
|
|
181
|
-
|
|
182
|
-
await client.queue('test-queue-v2-ns-multi-b')
|
|
183
|
-
.namespace(namespace)
|
|
184
|
-
.config({ priority: 5 })
|
|
185
|
-
.create()
|
|
186
|
-
|
|
187
|
-
await client.queue('test-queue-v2-ns-multi-c')
|
|
188
|
-
.namespace(namespace)
|
|
189
|
-
.config({ priority: 1 })
|
|
190
|
-
.create()
|
|
191
|
-
|
|
192
|
-
// Push to all
|
|
193
|
-
await client.queue('test-queue-v2-ns-multi-a').push([{ data: { from: 'a' } }])
|
|
194
|
-
await client.queue('test-queue-v2-ns-multi-b').push([{ data: { from: 'b' } }])
|
|
195
|
-
await client.queue('test-queue-v2-ns-multi-c').push([{ data: { from: 'c' } }])
|
|
196
|
-
|
|
197
|
-
// Consume from namespace (should get all 3)
|
|
198
|
-
const messages = []
|
|
199
|
-
await client.queue()
|
|
200
|
-
.namespace(namespace)
|
|
201
|
-
.batch(10)
|
|
202
|
-
.wait(false)
|
|
203
|
-
.limit(1)
|
|
204
|
-
.consume(async (msgs) => {
|
|
205
|
-
messages.push(...msgs)
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
return {
|
|
209
|
-
success: messages.length === 3,
|
|
210
|
-
message: `Namespace multi-queue: ${messages.length} messages`
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
export async function testEncryptedWithPartitionAndGroup(client) {
|
|
215
|
-
const queue = await client.queue('test-queue-v2-encrypted-complex')
|
|
216
|
-
.config({ encryptionEnabled: true })
|
|
217
|
-
.create()
|
|
218
|
-
|
|
219
|
-
if (!queue.configured) {
|
|
220
|
-
return { success: false, message: 'Queue not created' }
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// Push encrypted to partition
|
|
224
|
-
await client.queue('test-queue-v2-encrypted-complex')
|
|
225
|
-
.partition('secure-partition')
|
|
226
|
-
.push([{ data: { secret: 'sensitive-data', id: 123 } }])
|
|
227
|
-
|
|
228
|
-
// Consume with group
|
|
229
|
-
let receivedData = null
|
|
230
|
-
await client.queue('test-queue-v2-encrypted-complex')
|
|
231
|
-
.partition('secure-partition')
|
|
232
|
-
.group('secure-group')
|
|
233
|
-
.batch(1)
|
|
234
|
-
.wait(false)
|
|
235
|
-
.limit(1)
|
|
236
|
-
.each()
|
|
237
|
-
.consume(async (msg) => {
|
|
238
|
-
receivedData = msg.data
|
|
239
|
-
})
|
|
240
|
-
|
|
241
|
-
return {
|
|
242
|
-
success: receivedData && receivedData.secret === 'sensitive-data',
|
|
243
|
-
message: 'Encrypted + partition + group works'
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
export async function testHighConcurrencyMixedOperations(client) {
|
|
248
|
-
await client.queue('test-queue-v2-concurrency-mixed').create()
|
|
249
|
-
|
|
250
|
-
// Push many messages
|
|
251
|
-
const pushPromises = []
|
|
252
|
-
for (let i = 0; i < 50; i++) {
|
|
253
|
-
pushPromises.push(
|
|
254
|
-
client.queue('test-queue-v2-concurrency-mixed')
|
|
255
|
-
.push([{ data: { id: i } }])
|
|
256
|
-
)
|
|
257
|
-
}
|
|
258
|
-
await Promise.all(pushPromises)
|
|
259
|
-
|
|
260
|
-
// Consume with high concurrency
|
|
261
|
-
let processedCount = 0
|
|
262
|
-
await client.queue('test-queue-v2-concurrency-mixed')
|
|
263
|
-
.concurrency(10)
|
|
264
|
-
.batch(5)
|
|
265
|
-
.wait(false)
|
|
266
|
-
.limit(10)
|
|
267
|
-
.each()
|
|
268
|
-
.consume(async (msg) => {
|
|
269
|
-
processedCount++
|
|
270
|
-
await new Promise(resolve => setTimeout(resolve, 10))
|
|
271
|
-
})
|
|
272
|
-
|
|
273
|
-
return {
|
|
274
|
-
success: processedCount === 50,
|
|
275
|
-
message: `High concurrency mixed ops: ${processedCount} messages`
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
package/test-v2/ai_priority.js
DELETED
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Priority Queue Tests
|
|
3
|
-
* Tests for message priority handling
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export async function testBasicPriority(client) {
|
|
7
|
-
// Create queues with different priorities
|
|
8
|
-
const highPriorityQueue = await client.queue('test-queue-v2-priority-high')
|
|
9
|
-
.config({ priority: 10 })
|
|
10
|
-
.create()
|
|
11
|
-
|
|
12
|
-
const lowPriorityQueue = await client.queue('test-queue-v2-priority-low')
|
|
13
|
-
.config({ priority: 1 })
|
|
14
|
-
.create()
|
|
15
|
-
|
|
16
|
-
if (!highPriorityQueue.configured || !lowPriorityQueue.configured) {
|
|
17
|
-
return { success: false, message: 'Queues not created' }
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Push to low priority first
|
|
21
|
-
await client.queue('test-queue-v2-priority-low')
|
|
22
|
-
.push([{ data: { priority: 'low', message: 'Should process second' } }])
|
|
23
|
-
|
|
24
|
-
// Then push to high priority
|
|
25
|
-
await client.queue('test-queue-v2-priority-high')
|
|
26
|
-
.push([{ data: { priority: 'high', message: 'Should process first' } }])
|
|
27
|
-
|
|
28
|
-
// Note: Testing actual priority processing order requires namespace/task filtering
|
|
29
|
-
// as pop() from specific queue will only get that queue's messages
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
success: true,
|
|
33
|
-
message: 'Priority queues configured successfully'
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function testPriorityWithNamespace(client) {
|
|
38
|
-
const namespace = 'test-priority-namespace'
|
|
39
|
-
|
|
40
|
-
// Create multiple queues in same namespace with different priorities
|
|
41
|
-
await client.queue('test-queue-v2-pri-ns-high')
|
|
42
|
-
.namespace(namespace)
|
|
43
|
-
.config({ priority: 10 })
|
|
44
|
-
.create()
|
|
45
|
-
|
|
46
|
-
await client.queue('test-queue-v2-pri-ns-medium')
|
|
47
|
-
.namespace(namespace)
|
|
48
|
-
.config({ priority: 5 })
|
|
49
|
-
.create()
|
|
50
|
-
|
|
51
|
-
await client.queue('test-queue-v2-pri-ns-low')
|
|
52
|
-
.namespace(namespace)
|
|
53
|
-
.config({ priority: 1 })
|
|
54
|
-
.create()
|
|
55
|
-
|
|
56
|
-
// Push messages in reverse priority order
|
|
57
|
-
await client.queue('test-queue-v2-pri-ns-low')
|
|
58
|
-
.push([{ data: { order: 'third', value: 1 } }])
|
|
59
|
-
|
|
60
|
-
await client.queue('test-queue-v2-pri-ns-medium')
|
|
61
|
-
.push([{ data: { order: 'second', value: 5 } }])
|
|
62
|
-
|
|
63
|
-
await client.queue('test-queue-v2-pri-ns-high')
|
|
64
|
-
.push([{ data: { order: 'first', value: 10 } }])
|
|
65
|
-
|
|
66
|
-
// Pop from namespace (should respect priority)
|
|
67
|
-
const messages = []
|
|
68
|
-
await client.queue()
|
|
69
|
-
.namespace(namespace)
|
|
70
|
-
.batch(3)
|
|
71
|
-
.wait(false)
|
|
72
|
-
.limit(1)
|
|
73
|
-
.consume(async (msgs) => {
|
|
74
|
-
messages.push(...msgs)
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
// Messages should be in priority order
|
|
78
|
-
if (messages.length !== 3) {
|
|
79
|
-
return { success: false, message: `Expected 3 messages, got ${messages.length}` }
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// High priority should come first
|
|
83
|
-
const firstIsHighPriority = messages[0].data.value === 10
|
|
84
|
-
|
|
85
|
-
return {
|
|
86
|
-
success: firstIsHighPriority,
|
|
87
|
-
message: `Priority ordering: ${messages.map(m => m.data.order).join(', ')}`
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export async function testPriorityWithTask(client) {
|
|
92
|
-
const task = 'test-priority-task'
|
|
93
|
-
|
|
94
|
-
// Create queues with same task but different priorities
|
|
95
|
-
await client.queue('test-queue-v2-pri-task-urgent')
|
|
96
|
-
.task(task)
|
|
97
|
-
.config({ priority: 100 })
|
|
98
|
-
.create()
|
|
99
|
-
|
|
100
|
-
await client.queue('test-queue-v2-pri-task-normal')
|
|
101
|
-
.task(task)
|
|
102
|
-
.config({ priority: 50 })
|
|
103
|
-
.create()
|
|
104
|
-
|
|
105
|
-
// Push to normal first
|
|
106
|
-
await client.queue('test-queue-v2-pri-task-normal')
|
|
107
|
-
.push([{ data: { urgency: 'normal' } }])
|
|
108
|
-
|
|
109
|
-
// Then urgent
|
|
110
|
-
await client.queue('test-queue-v2-pri-task-urgent')
|
|
111
|
-
.push([{ data: { urgency: 'urgent' } }])
|
|
112
|
-
|
|
113
|
-
// Pop from task
|
|
114
|
-
const messages = []
|
|
115
|
-
await client.queue()
|
|
116
|
-
.task(task)
|
|
117
|
-
.batch(2)
|
|
118
|
-
.wait(false)
|
|
119
|
-
.limit(1)
|
|
120
|
-
.consume(async (msgs) => {
|
|
121
|
-
messages.push(...msgs)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
if (messages.length !== 2) {
|
|
125
|
-
return { success: false, message: `Expected 2 messages, got ${messages.length}` }
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Urgent should come first
|
|
129
|
-
const urgentFirst = messages[0].data.urgency === 'urgent'
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
success: urgentFirst,
|
|
133
|
-
message: 'Task-based priority ordering works'
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export async function testDynamicPriorityChange(client) {
|
|
138
|
-
const queueName = 'test-queue-v2-priority-dynamic'
|
|
139
|
-
|
|
140
|
-
// Create with low priority
|
|
141
|
-
await client.queue(queueName)
|
|
142
|
-
.config({ priority: 1 })
|
|
143
|
-
.create()
|
|
144
|
-
|
|
145
|
-
// Push a message
|
|
146
|
-
await client.queue(queueName)
|
|
147
|
-
.push([{ data: { phase: 'low-priority' } }])
|
|
148
|
-
|
|
149
|
-
// Reconfigure with high priority
|
|
150
|
-
await client.queue(queueName)
|
|
151
|
-
.config({ priority: 10 })
|
|
152
|
-
.create()
|
|
153
|
-
|
|
154
|
-
// Push another message
|
|
155
|
-
await client.queue(queueName)
|
|
156
|
-
.push([{ data: { phase: 'high-priority' } }])
|
|
157
|
-
|
|
158
|
-
// Pop messages
|
|
159
|
-
const messages = await client.queue(queueName)
|
|
160
|
-
.batch(2)
|
|
161
|
-
.wait(false)
|
|
162
|
-
.pop()
|
|
163
|
-
|
|
164
|
-
return {
|
|
165
|
-
success: messages.length === 2,
|
|
166
|
-
message: 'Dynamic priority change handled'
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|