Fix: SQS fails to get newly-visible messages when long polling (#5733)

The [original commit to remove the `sleep` call][1], only considered newly-arriving
messages; but didn't take into account that existing messages could become visible
in a much shorter time duration than the wait timeout.  This commit addresses this
by checking for newly-visible messages at the visibility timeout granularity (seconds),
which is still a major improvement over the original 10 millisecond polling.

[1]: <d560ff002d> "Remove Sleep Call"
This commit is contained in:
Brian Pandola 2022-12-04 18:00:56 -08:00 committed by GitHub
parent d10a8e9900
commit 7c44e48670
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 1 deletions

View File

@ -949,7 +949,7 @@ class SQSBackend(BaseBackend):
# so break to avoid an infinite loop. # so break to avoid an infinite loop.
break break
queue.wait_for_messages(wait_seconds_timeout) queue.wait_for_messages(1)
continue continue
previous_result_count = len(result) previous_result_count = len(result)

View File

@ -3180,3 +3180,20 @@ def test_message_delay_is_more_than_15_minutes():
response["Messages"][0]["Attributes"]["MessageDeduplicationId"].should.equal( response["Messages"][0]["Attributes"]["MessageDeduplicationId"].should.equal(
"message_deduplication_id_1" "message_deduplication_id_1"
) )
@mock_sqs
def test_receive_message_that_becomes_visible_while_long_polling():
sqs = boto3.resource("sqs", region_name="us-east-1")
queue = sqs.create_queue(QueueName="test-queue")
msg_body = str(uuid4())
queue.send_message(MessageBody=msg_body)
messages = queue.receive_messages()
messages[0].change_visibility(VisibilityTimeout=1)
time_to_wait = 2
begin = time.time()
messages = queue.receive_messages(WaitTimeSeconds=time_to_wait)
end = time.time()
assert len(messages) == 1
assert messages[0].body == msg_body
assert end - begin < time_to_wait