Respect VisibilityTimeout when calling receive_message
Previously, receive_message would always use the queue's default visibility timeout instead of the value passed as a query parameter when calling the receive_message method on an SQS connection.
This commit is contained in:
		
							parent
							
								
									4372c346d9
								
							
						
					
					
						commit
						9b7902018f
					
				| @ -265,7 +265,7 @@ class SQSBackend(BaseBackend): | |||||||
| 
 | 
 | ||||||
|         return message |         return message | ||||||
| 
 | 
 | ||||||
|     def receive_messages(self, queue_name, count, wait_seconds_timeout): |     def receive_messages(self, queue_name, count, wait_seconds_timeout, visibility_timeout): | ||||||
|         """ |         """ | ||||||
|         Attempt to retrieve visible messages from a queue. |         Attempt to retrieve visible messages from a queue. | ||||||
| 
 | 
 | ||||||
| @ -276,6 +276,7 @@ class SQSBackend(BaseBackend): | |||||||
| 
 | 
 | ||||||
|         :param string queue_name: The name of the queue to read from. |         :param string queue_name: The name of the queue to read from. | ||||||
|         :param int count: The maximum amount of messages to retrieve. |         :param int count: The maximum amount of messages to retrieve. | ||||||
|  |         :param int visibility_timeout: The number of seconds the message should remain invisible to other queue readers. | ||||||
|         """ |         """ | ||||||
|         queue = self.get_queue(queue_name) |         queue = self.get_queue(queue_name) | ||||||
|         result = [] |         result = [] | ||||||
| @ -288,7 +289,7 @@ class SQSBackend(BaseBackend): | |||||||
|                 if not message.visible: |                 if not message.visible: | ||||||
|                     continue |                     continue | ||||||
|                 message.mark_received( |                 message.mark_received( | ||||||
|                     visibility_timeout=queue.visibility_timeout |                     visibility_timeout=visibility_timeout | ||||||
|                 ) |                 ) | ||||||
|                 result.append(message) |                 result.append(message) | ||||||
|                 if len(result) >= count: |                 if len(result) >= count: | ||||||
|  | |||||||
| @ -38,6 +38,18 @@ class SQSResponse(BaseResponse): | |||||||
|             queue_name = self.path.split("/")[-1] |             queue_name = self.path.split("/")[-1] | ||||||
|         return queue_name |         return queue_name | ||||||
| 
 | 
 | ||||||
|  |     def _get_validated_visibility_timeout(self): | ||||||
|  |         """ | ||||||
|  |         :raises ValueError: If specified visibility timeout exceeds MAXIMUM_VISIBILTY_TIMEOUT | ||||||
|  |         :raises TypeError: If visibility timeout was not specified | ||||||
|  |         """ | ||||||
|  |         visibility_timeout = int(self.querystring.get("VisibilityTimeout")[0]) | ||||||
|  | 
 | ||||||
|  |         if visibility_timeout > MAXIMUM_VISIBILTY_TIMEOUT: | ||||||
|  |             raise ValueError | ||||||
|  | 
 | ||||||
|  |         return visibility_timeout | ||||||
|  | 
 | ||||||
|     def create_queue(self): |     def create_queue(self): | ||||||
|         queue_name = self.querystring.get("QueueName")[0] |         queue_name = self.querystring.get("QueueName")[0] | ||||||
|         queue = self.sqs_backend.create_queue(queue_name, visibility_timeout=self.attribute.get('VisibilityTimeout'), |         queue = self.sqs_backend.create_queue(queue_name, visibility_timeout=self.attribute.get('VisibilityTimeout'), | ||||||
| @ -63,12 +75,11 @@ class SQSResponse(BaseResponse): | |||||||
|     def change_message_visibility(self): |     def change_message_visibility(self): | ||||||
|         queue_name = self._get_queue_name() |         queue_name = self._get_queue_name() | ||||||
|         receipt_handle = self.querystring.get("ReceiptHandle")[0] |         receipt_handle = self.querystring.get("ReceiptHandle")[0] | ||||||
|         visibility_timeout = int(self.querystring.get("VisibilityTimeout")[0]) |  | ||||||
| 
 | 
 | ||||||
|         if visibility_timeout > MAXIMUM_VISIBILTY_TIMEOUT: |         try: | ||||||
|             return "Invalid request, maximum visibility timeout is {0}".format( |             visibility_timeout = self._get_validated_visibility_timeout() | ||||||
|                 MAXIMUM_VISIBILTY_TIMEOUT |         except ValueError: | ||||||
|             ), dict(status=400) |             return ERROR_MAX_VISIBILITY_TIMEOUT_RESPONSE, dict(status=400) | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|             self.sqs_backend.change_message_visibility( |             self.sqs_backend.change_message_visibility( | ||||||
| @ -233,7 +244,14 @@ class SQSResponse(BaseResponse): | |||||||
|         except TypeError: |         except TypeError: | ||||||
|             wait_time = queue.wait_time_seconds |             wait_time = queue.wait_time_seconds | ||||||
| 
 | 
 | ||||||
|         messages = self.sqs_backend.receive_messages(queue_name, message_count, wait_time) |         try: | ||||||
|  |             visibility_timeout = self._get_validated_visibility_timeout() | ||||||
|  |         except TypeError: | ||||||
|  |             visibility_timeout = queue.visibility_timeout | ||||||
|  |         except ValueError: | ||||||
|  |             return ERROR_MAX_VISIBILITY_TIMEOUT_RESPONSE, dict(status=400) | ||||||
|  | 
 | ||||||
|  |         messages = self.sqs_backend.receive_messages(queue_name, message_count, wait_time, visibility_timeout) | ||||||
|         template = self.response_template(RECEIVE_MESSAGE_RESPONSE) |         template = self.response_template(RECEIVE_MESSAGE_RESPONSE) | ||||||
|         output = template.render(messages=messages) |         output = template.render(messages=messages) | ||||||
|         return output |         return output | ||||||
| @ -436,3 +454,5 @@ ERROR_TOO_LONG_RESPONSE = """<ErrorResponse xmlns="http://queue.amazonaws.com/do | |||||||
|     </Error> |     </Error> | ||||||
|     <RequestId>6fde8d1e-52cd-4581-8cd9-c512f4c64223</RequestId> |     <RequestId>6fde8d1e-52cd-4581-8cd9-c512f4c64223</RequestId> | ||||||
| </ErrorResponse>""" | </ErrorResponse>""" | ||||||
|  | 
 | ||||||
|  | ERROR_MAX_VISIBILITY_TIMEOUT_RESPONSE = "Invalid request, maximum visibility timeout is {0}".format(MAXIMUM_VISIBILTY_TIMEOUT) | ||||||
|  | |||||||
| @ -203,6 +203,23 @@ def test_message_becomes_inflight_when_received(): | |||||||
|     queue.count().should.equal(1) |     queue.count().should.equal(1) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @mock_sqs | ||||||
|  | def test_receive_message_with_explicit_visibility_timeout(): | ||||||
|  |     conn = boto.connect_sqs('the_key', 'the_secret') | ||||||
|  |     queue = conn.create_queue("test-queue", visibility_timeout=60) | ||||||
|  |     queue.set_message_class(RawMessage) | ||||||
|  | 
 | ||||||
|  |     body_one = 'this is another test message' | ||||||
|  |     queue.write(queue.new_message(body_one)) | ||||||
|  | 
 | ||||||
|  |     queue.count().should.equal(1) | ||||||
|  |     messages = conn.receive_message(queue, number_messages=1, visibility_timeout=0) | ||||||
|  | 
 | ||||||
|  |     assert len(messages) == 1 | ||||||
|  | 
 | ||||||
|  |     # Message should remain visible | ||||||
|  |     queue.count().should.equal(1) | ||||||
|  | 
 | ||||||
| @mock_sqs | @mock_sqs | ||||||
| def test_change_message_visibility(): | def test_change_message_visibility(): | ||||||
|     conn = boto.connect_sqs('the_key', 'the_secret') |     conn = boto.connect_sqs('the_key', 'the_secret') | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user