Ack & Reject
Selectively acknowledge or reject individual KubeMQ queue messages in Node.js to confirm successes and discard failed deliveries.
Overview
Ack and reject give you per-message control over queue delivery instead of an all-or-nothing batch outcome. When receiveQueueMessages() fetches a batch, each message stays locked on the broker — invisible to other consumers — until the consumer explicitly settles it. That's what you need when one bad record in a batch shouldn't take the rest down with it.
Settlement happens through two calls on the received message: msg.ack(), which permanently removes it from the queue, and msg.nack(), which returns it to the queue for redelivery (or routes it to the dead-letter queue if maxReceiveQueue is configured). Internally the broker tracks this against a receive count, which a dead-letter policy can use to stop retrying a poison message forever.
Gotchas: an unsettled message isn't gone — it snaps back to the queue once the visibility timeout expires, so a slow consumer looks identical to a rejecting one; settle every message before that deadline, and never assume a batch is fully processed until you've called ack() or nack() on each one individually.
Prerequisites
- KubeMQ server running on
localhost:50000 - Node.js SDK installed (
npm install kubemq-js)
Code
/**
* Example: Message Acknowledgment and Rejection
*
* Demonstrates the two message handling options after receiving a queue
* message via simple receive: acknowledge (success) or reject (send to
* dead-letter queue).
*
* Prerequisites:
* - KubeMQ server running on localhost:50000
*
* Run: npx tsx examples/queues/ack-reject.ts
*/
import { KubeMQClient, createQueueMessage } from 'kubemq-js';
async function main(): Promise<void> {
const client = await KubeMQClient.create({
address: 'localhost:50000',
clientId: 'js-queues-ack-reject-client',
});
try {
// Send test messages with different intents.
for (const task of ['valid-task', 'bad-format', 'another-valid-task']) {
await client.sendQueueMessage(
createQueueMessage({
channel: 'js-queues.ack-reject',
body: task,
tags: { type: task },
}),
);
}
const messages = await client.receiveQueueMessages({
channel: 'js-queues.ack-reject',
waitTimeoutSeconds: 5,
maxMessages: 10,
});
for (const msg of messages) {
const body = new TextDecoder().decode(msg.body);
if (body === 'bad-format') {
// Permanently reject — message goes to dead-letter queue if configured.
await msg.nack();
console.log('Rejected:', body);
} else {
// Acknowledge successful processing.
await msg.ack();
console.log('Acknowledged:', body);
}
}
} finally {
await client.close();
}
}
main().catch(console.error);
How It Works
receiveQueueMessages()withmaxMessages: 10fetches up to 10 messages in a single poll and locks them for processing.await msg.ack()marks the message as successfully processed — it is permanently removed from the queue.await msg.nack()permanently rejects the message: ifmaxReceiveQueueis configured on the message policy the message moves to the dead-letter queue; otherwise it is discarded.- Each ack/nack must be called before the visibility timeout expires; the
waitTimeoutSecondson the receive controls how long the server waits for a consumer, not the ack deadline.
Related
Was this page helpful?