Skip to main content

Workers

The QueueWorker class in the Rinda SDK provides a reliable, production-ready message consumer with automatic polling, error handling, and graceful shutdown.

Creating a Worker​

Create a worker from a queue handle:

import { Rinda } from '@rindahq/sdk';

const rinda = new Rinda({ apiKey: process.env.RINDA_API_KEY });
const q = rinda.queue('QUEUE_ID');

const worker = q.createWorker({
handler: async (message) => {
console.log('Processing:', message.body);
// Your processing logic here
return message; // Acknowledge — message is auto-deleted
},
});

worker.start();
console.log('Worker running:', worker.isRunning); // true

Configuration Options​

const worker = q.createWorker({
handler: async (message) => {
await processOrder(message.body);
return message;
},
batchSize: 5, // Messages per poll (1-10, default: 1)
visibilityTimeout: 60, // Seconds before message reappears (default: 30)
waitTimeSeconds: 20, // Long-poll duration (0-20, default: 20)
pollingWaitTimeMs: 0, // Delay between polls in ms (default: 0)
shouldDeleteMessages: true, // Auto-delete on success (default: true)
});
OptionDefaultDescription
handler—Async function to process a single message
batchHandler—Async function to process a batch of messages
batchSize1 / 10Messages per poll (1 for handler, 10 for batchHandler)
visibilityTimeout30Seconds before unacknowledged message reappears
waitTimeSeconds20Long-poll wait time in seconds
pollingWaitTimeMs0Delay between polling cycles in ms
shouldDeleteMessagestrueAuto-delete messages after successful processing
tip

Provide either handler (single message) or batchHandler (batch), not both.

Batch Handler​

Process multiple messages at once for higher throughput:

const worker = q.createWorker({
batchHandler: async (messages) => {
console.log(`Processing batch of ${messages.length} message(s)`);

for (const msg of messages) {
await processOrder(msg.body);
}

return messages; // Acknowledge all
},
batchSize: 10,
});

worker.start();

Error Handling​

If the handler throws an error, the message is not deleted and becomes visible again after the visibility timeout:

const worker = q.createWorker({
handler: async (message) => {
const order = message.body;

if (!order.id) {
throw new Error('Invalid order — missing ID');
// Message will be retried, eventually going to DLQ
}

await processOrder(order);
return message; // Auto-deleted on success
},
});

Worker Events​

Listen for lifecycle events:

const worker = q.createWorker({ handler });

worker.on('message_received', (msg) => {
console.log('Received:', msg.id);
});

worker.on('message_processed', (msg) => {
console.log('Processed:', msg.id);
});

worker.on('processing_error', (err, msg) => {
console.error('Failed:', msg.id, err.message);
});

worker.on('error', (err) => {
console.error('Worker error:', err);
});

worker.on('empty', () => {
console.log('Queue is empty');
});

worker.start();

Graceful Shutdown​

Stop the worker gracefully to finish processing in-flight messages:

const worker = q.createWorker({ handler });
worker.start();

// Handle shutdown signals
process.on('SIGTERM', () => {
console.log('Shutting down worker...');
worker.stop(); // Finishes in-flight messages
});

process.on('SIGINT', () => {
worker.stop();
});

Multiple Workers​

Run multiple workers for different queues or parallel processing:

const orderQueue = rinda.queue('ORDER_QUEUE_ID');
const notificationQueue = rinda.queue('NOTIFICATION_QUEUE_ID');

const orderWorker = orderQueue.createWorker({
handler: processOrder,
batchSize: 5,
});

const notificationWorker = notificationQueue.createWorker({
handler: sendNotification,
batchSize: 10,
});

orderWorker.start();
notificationWorker.start();

Best Practices​

  1. Use long-polling — Set waitTimeSeconds: 20 to minimize API calls and cost
  2. Enable DLQ — Configure dead-letter queues so failed messages don't block the queue
  3. Handle signals — Always implement graceful shutdown to avoid message loss
  4. Keep handlers idempotent — Messages may be delivered more than once (standard queues)
  5. Set appropriate visibility timeouts — Match to your expected processing time plus buffer
  6. Return the message — Always return message (or return messages for batch) to acknowledge successful processing