queen-mq 0.12.0 → 0.12.1
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.
|
@@ -13,10 +13,10 @@ export class TransactionBuilder {
|
|
|
13
13
|
this.#httpClient = httpClient
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
ack(messages, status = 'completed') {
|
|
16
|
+
ack(messages, status = 'completed', context = {}) {
|
|
17
17
|
const msgs = Array.isArray(messages) ? messages : [messages]
|
|
18
18
|
|
|
19
|
-
logger.log('TransactionBuilder.ack', { count: msgs.length, status })
|
|
19
|
+
logger.log('TransactionBuilder.ack', { count: msgs.length, status, consumerGroup: context.consumerGroup })
|
|
20
20
|
|
|
21
21
|
msgs.forEach(msg => {
|
|
22
22
|
const transactionId = typeof msg === 'string' ? msg : (msg.transactionId || msg.id)
|
|
@@ -32,12 +32,19 @@ export class TransactionBuilder {
|
|
|
32
32
|
throw new Error('Message must have partitionId property to ensure message uniqueness')
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
const operation = {
|
|
36
36
|
type: 'ack',
|
|
37
37
|
transactionId,
|
|
38
38
|
partitionId,
|
|
39
39
|
status
|
|
40
|
-
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Add consumerGroup if provided in context
|
|
43
|
+
if (context.consumerGroup) {
|
|
44
|
+
operation.consumerGroup = context.consumerGroup
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
this.#operations.push(operation)
|
|
41
48
|
|
|
42
49
|
if (leaseId) {
|
|
43
50
|
this.#requiredLeases.push(leaseId)
|
package/package.json
CHANGED
package/test-v2/transaction.js
CHANGED
|
@@ -503,3 +503,69 @@ export async function transactionRollback(client) {
|
|
|
503
503
|
}
|
|
504
504
|
}
|
|
505
505
|
|
|
506
|
+
export async function transactionAckWithConsumerGroup(client) {
|
|
507
|
+
const queueA = await client.queue('test-queue-v2-txn-cg-a').create()
|
|
508
|
+
const queueB = await client.queue('test-queue-v2-txn-cg-b').create()
|
|
509
|
+
if (!queueA.configured || !queueB.configured) {
|
|
510
|
+
return { success: false, message: 'Queues not created' }
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
const consumerGroup = 'test-consumer-group-txn'
|
|
514
|
+
|
|
515
|
+
// Push messages to queue A
|
|
516
|
+
await client.queue('test-queue-v2-txn-cg-a').push([
|
|
517
|
+
{ data: { value: 1 } },
|
|
518
|
+
{ data: { value: 2 } }
|
|
519
|
+
])
|
|
520
|
+
|
|
521
|
+
// Pop with consumer group
|
|
522
|
+
const messages = await client.queue('test-queue-v2-txn-cg-a')
|
|
523
|
+
.group(consumerGroup)
|
|
524
|
+
.batch(2)
|
|
525
|
+
.wait(false)
|
|
526
|
+
.pop()
|
|
527
|
+
|
|
528
|
+
if (messages.length !== 2) {
|
|
529
|
+
return { success: false, message: `Expected 2 messages, got ${messages.length}` }
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Transaction: ACK with consumer group context, push to B
|
|
533
|
+
await client
|
|
534
|
+
.transaction()
|
|
535
|
+
.ack(messages[0], 'completed', { consumerGroup })
|
|
536
|
+
.ack(messages[1], 'completed', { consumerGroup })
|
|
537
|
+
.queue('test-queue-v2-txn-cg-b')
|
|
538
|
+
.push([{ data: { sum: messages[0].data.value + messages[1].data.value } }])
|
|
539
|
+
.commit()
|
|
540
|
+
|
|
541
|
+
// Verify: Pop again with same consumer group should get no messages
|
|
542
|
+
// (consumer group cursor should have advanced)
|
|
543
|
+
const messagesAfterAck = await client.queue('test-queue-v2-txn-cg-a')
|
|
544
|
+
.group(consumerGroup)
|
|
545
|
+
.batch(2)
|
|
546
|
+
.wait(false)
|
|
547
|
+
.pop()
|
|
548
|
+
|
|
549
|
+
// Verify: Queue B has the result
|
|
550
|
+
const resultB = await client.queue('test-queue-v2-txn-cg-b').batch(1).wait(false).pop()
|
|
551
|
+
|
|
552
|
+
// Verify: Using a different consumer group should still see the messages
|
|
553
|
+
const messagesOtherGroup = await client.queue('test-queue-v2-txn-cg-a')
|
|
554
|
+
.group('other-consumer-group')
|
|
555
|
+
.batch(2)
|
|
556
|
+
.wait(false)
|
|
557
|
+
.pop()
|
|
558
|
+
|
|
559
|
+
const success = messagesAfterAck.length === 0 &&
|
|
560
|
+
resultB.length === 1 &&
|
|
561
|
+
resultB[0].data.sum === 3 &&
|
|
562
|
+
messagesOtherGroup.length === 2
|
|
563
|
+
|
|
564
|
+
return {
|
|
565
|
+
success,
|
|
566
|
+
message: success
|
|
567
|
+
? 'Transaction ack with consumer group completed - cursor advanced correctly'
|
|
568
|
+
: `Failed: afterAck=${messagesAfterAck.length} (expected 0), resultB=${resultB.length} (expected 1), otherGroup=${messagesOtherGroup.length} (expected 2)`
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|