What is the best way to poll for messages from Amazon Web Services SQS? I want to handle the messages as soon as they are in the queue and don't really want to poll every second unless this is the only option?
setInterval(run(), 1000);
I get the error
const run: () => Promise<void>
//---------------------------------
No overload matches this call.
Overload 1 of 2, '(callback: (...args: any[]) => void, ms: number, ...args: any[]): Timeout', gave the following error.
Argument of type 'Promise<void>' is not assignable to parameter of type '(...args: any[]) => void'.
Type 'Promise<void>' provides no match for the signature '(...args: any[]): void'.
Overload 2 of 2, '(handler: TimerHandler, timeout?: number, ...arguments: any[]): number', gave the following error.
Argument of type 'Promise<void>' is not assignable to parameter of type 'TimerHandler'.
Type 'Promise<void>' is missing the following properties from type 'Function': apply, call, bind, prototype, and 5 more.ts(2769)`
my code...
const QueueUrl = process.env.SQS_QUEUE_URL;
const params = {
AttributeNames: ['SentTimestamp'],
MaxNumberOfMessages: 10,
MessageAttributeNames: ['All'],
QueueUrl,
VisibilityTimeout: 20,
WaitTimeSeconds: 0,
};
const sqs = new SQSClient({ region: process.env.SQS_REGION });
const run = async () => {
try {
const data = await sqs.send(new ReceiveMessageCommand(params));
if (data.Messages) {
for (const val of data.Messages) {
const address = val.MessageAttributes.Address.StringValue;
const amount = Number(val.MessageAttributes.Amount.StringValue);
createTransaction(address, amount);
const deleteParams = {
QueueUrl,
ReceiptHandle: val.ReceiptHandle,
};
try {
await sqs.send(new DeleteMessageCommand(deleteParams));
} catch (err) {
// tslint:disable-next-line: no-console
console.log('Message Deleted', data);
}
}
} else {
// tslint:disable-next-line: no-console
console.log('No messages to delete');
}
} catch (err) {
// tslint:disable-next-line: no-console
console.log('Receive Error', err);
}
};
run();
When calling ReceiveMessage
, you can specify WaitTimeSeconds
up to 20 seconds. This is known as Long Polling.
It works like this:
WaitTimeSeconds
period, the call will return as soon as messages are availableWaitTimeSeconds
period, then the call will return with no messagesThis means you can call ReceiveMessage
in a loop, but if there are no messages, it will wait up to 20 seconds before it returns. This is better than "polling every second".
Alternatively, you could put your code in an AWS Lambda function and configure the Amazon SQS queue as a trigger for the function. When a message is sent to the queue, the Lambda function will automatically be invoked, with the message(s) being passed into the function via the event
parameter (without needing to call ReceiveMessage
).