@@ -24,6 +24,8 @@ class SQSBroker(AsyncBroker):
2424 def __init__ (
2525 self ,
2626 sqs_queue_url : str ,
27+ wait_time_seconds : int = 0 , # Used for long polling
28+ max_number_of_messages : int = 1 , # size of batch to receive from the queue
2729 result_backend : Optional [AsyncResultBackend ] = None ,
2830 task_id_generator : Optional [Callable [[], str ]] = None ,
2931 ) -> None :
@@ -32,6 +34,9 @@ def __init__(
3234 self ._sqs = boto3 .resource ("sqs" )
3335 self ._sqs_queue : Optional [Queue ] = None
3436
37+ self .wait_time_seconds = wait_time_seconds
38+ self .max_number_of_messages = max_number_of_messages
39+
3540 async def _get_queue (self ) -> Queue :
3641 queue_name = self .sqs_queue_url .split ("/" )[- 1 ]
3742
@@ -100,7 +105,13 @@ async def listen(self) -> AsyncGenerator[Union[bytes, AckableMessage], None]:
100105 last_had_message = False
101106
102107 for message in await asyncify (queue .receive_messages )(
103- MessageAttributeNames = [".*" ]
108+ MessageAttributeNames = [".*" ],
109+ # If there's competition on this queue (multiple processes of workers pulling from
110+ # the same queue), and processing takes longer than the visibility timeout, multiple
111+ # workers may end up processing the same message.
112+ MaxNumberOfMessages = self .max_number_of_messages ,
113+ # Use long poling.
114+ WaitTimeSeconds = self .wait_time_seconds ,
104115 ):
105116 try :
106117 if message .message_attributes :
0 commit comments