Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get messages receive count in Amazon SQS using boto library in Python?

I am using boto library in Python to get Amazon SQS messages. In exceptional cases I don't delete messages from queue in order to give a couple of more changes to recover temporary failures. But I don't want to keep receiving failed messages constantly. What I would like to do is either delete messages after receiving more than 3 times or not get message if receive count is more than 3.

What is the most elegant way of doing it?

like image 670
huzeyfe Avatar asked Aug 10 '12 12:08

huzeyfe


People also ask

How many messages can SQS receive?

A single Amazon SQS message queue can contain an unlimited number of messages. However, there is a quota of 120,000 for the number of inflight messages for a standard queue and 20,000 for a FIFO queue.

How do I read messages from SQS queue in Python?

To receive a message from an AWS SQS Python Queue, you can use receive_message() Boto3 method. The receive_message() SQS Python method retrieves one or more messages (up to 10), from your specified SQS Queue. Parameters: QueueUrl: The URL of the Amazon SQS Queue to which you wish to send a message.


3 Answers

There are at least a couple of ways of doing this.

When you read a message in boto, you receive a Message object or some subclass thereof. The Message object has an "attributes" field that is a dict containing all message attributes known by SQS. One of the things SQS tracks is the approximate # of times the message has been read. So, you could use this value to determine whether the message should be deleted or not but you would have to be comfortable with the "approximate" nature of the value.

Alternatively, you could record message ID's in some sort of database and increment a count field in the database each time you read the message. This could be done in a simple Python dict if the messages are always being read within a single process or it could be done in something like SimpleDB if you need to record readings across processes.

Hope that helps.

Here's some example code:

>>> import boto.sqs
>>> c = boto.sqs.connect_to_region()
>>> q = c.lookup('myqueue')
>>> messages = c.receive_message(q, num_messages=1, attributes='All')
>>> messages[0].attributes
{u'ApproximateFirstReceiveTimestamp': u'1365474374620',
 u'ApproximateReceiveCount': u'2',
 u'SenderId': u'419278470775',
 u'SentTimestamp': u'1365474360357'}
>>>
like image 156
garnaat Avatar answered Sep 24 '22 16:09

garnaat


Other way could be you can put an extra identifier at the end of the message in your SQS queue. This identifier can keep the count of the number of times the message has been read.

Also if you want that your service should not poll these message again and again then you can create one more queue say "Dead Message Queue" and can transfer then message which has crossed the threshold to this queue.

like image 33
Mayank Singal Avatar answered Sep 23 '22 16:09

Mayank Singal


aws has in-built support for this, just follow the below steps:

  1. create a dead letter queue
  2. enable Redrive policy for the source queue by checking "Use Redrive Policy"
  3. select the dead letter queue you created in step#1 for "Dead Letter Queue"
  4. Set "Maximum Receives" as "3" or any value between 1 and 1000

How it works is, whenever a message is received by the worker, the receive count increments. Once it reaches "Maximum Receives" count, the message is pushed to the dead letter queue. Note, even if you access the message via aws console, the receive count increments.

Source Using Amazon SQS Dead Letter Queues

like image 22
Sunil Manheri Avatar answered Sep 24 '22 16:09

Sunil Manheri