Reputation: 5150
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();
Upvotes: 1
Views: 1929
Reputation: 269081
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
).
Upvotes: 2
Reputation: 10704
If you want to retrieve messages on a regular basis (for example, every 2-3 mins), one way you can achieve this use case is to write a Lambda function that uses the SQS API and then call receiveMesage (what you do with the messages is up to you). Then schedule the Lambda function to be invoked using Cloud Watch event. You can use a CRON expression to define how often the Lambda function is invoked.
Upvotes: 1