99from taskiq import AsyncBroker
1010from taskiq .abc .result_backend import AsyncResultBackend
1111from taskiq .acks import AckableMessage
12+ from taskiq .exceptions import BrokerError
1213from taskiq .message import BrokerMessage
1314
1415logger = logging .getLogger (__name__ )
@@ -24,6 +25,8 @@ class SQSBroker(AsyncBroker):
2425 def __init__ (
2526 self ,
2627 sqs_queue_url : str ,
28+ wait_time_seconds : int = 0 , # Used for long polling
29+ max_number_of_messages : int = 1 , # size of batch to receive from the queue
2730 result_backend : Optional [AsyncResultBackend ] = None ,
2831 task_id_generator : Optional [Callable [[], str ]] = None ,
2932 ) -> None :
@@ -32,6 +35,12 @@ def __init__(
3235 self ._sqs = boto3 .resource ("sqs" )
3336 self ._sqs_queue : Optional [Queue ] = None
3437
38+ if max_number_of_messages > 10 :
39+ raise BrokerError ("MaxNumberOfMessages can be no greater than 10" )
40+
41+ self .wait_time_seconds = max (wait_time_seconds , 0 )
42+ self .max_number_of_messages = max (max_number_of_messages , 1 )
43+
3544 async def _get_queue (self ) -> Queue :
3645 queue_name = self .sqs_queue_url .split ("/" )[- 1 ]
3746
@@ -100,7 +109,13 @@ async def listen(self) -> AsyncGenerator[Union[bytes, AckableMessage], None]:
100109 no_backoff = False
101110
102111 for message in await asyncify (queue .receive_messages )(
103- MessageAttributeNames = [".*" ]
112+ MessageAttributeNames = [".*" ],
113+ # If there's competition on this queue (multiple processes of workers pulling from
114+ # the same queue), and processing takes longer than the visibility timeout, multiple
115+ # workers may end up processing the same message.
116+ MaxNumberOfMessages = self .max_number_of_messages ,
117+ # Use long poling.
118+ WaitTimeSeconds = self .wait_time_seconds ,
104119 ):
105120 try :
106121 if message .message_attributes :
0 commit comments