11import asyncio
22import logging
33from datetime import datetime , timezone
4- from typing import (
5- AsyncGenerator ,
6- Callable ,
7- Optional ,
8- Union ,
9- )
4+ from typing import AsyncGenerator , Callable , Optional , Union
105
116import boto3
12- from ape .logging import logger
137from asyncer import asyncify
148from mypy_boto3_sqs .service_resource import Queue
159from taskiq import AsyncBroker
1812from taskiq .message import BrokerMessage
1913
2014logger = logging .getLogger (__name__ )
21- stamp = lambda : int (datetime .now (tz = timezone .utc ).timestamp ())
15+
16+
17+ def stamp () -> int :
18+ return int (datetime .now (tz = timezone .utc ).timestamp ())
2219
2320
2421class SQSBroker (AsyncBroker ):
@@ -39,7 +36,9 @@ async def _get_queue(self) -> Queue:
3936 queue_name = self .sqs_queue_url .split ("/" )[- 1 ]
4037
4138 if not self ._sqs_queue :
42- self ._sqs_queue = await asyncify (self ._sqs .get_queue_by_name )(QueueName = queue_name )
39+ self ._sqs_queue = await asyncify (self ._sqs .get_queue_by_name )(
40+ QueueName = queue_name
41+ )
4342
4443 if not self ._sqs_queue :
4544 raise Exception ("SQS Queue not found" )
@@ -63,18 +62,16 @@ async def kick(
6362 """
6463 queue = await self ._get_queue ()
6564 # Must be explicitly set as a label to a unix timestamp
66- expiry = message .labels .pop ("sqs_expiry" , None )
67-
68- # SQS structured message attributes
69- message_attributes = dict ()
70- if expiry :
71- message_attributes ["expiry" ] = {
72- "StringValue" : str (expiry ),
73- "DataType" : "Number" ,
74- }
65+ expiry = message .labels .pop ("sqs_expiry" , 0 )
7566
7667 await asyncify (queue .send_message )(
77- MessageAttributes = message_attributes ,
68+ # SQS structured message attributes
69+ MessageAttributes = {
70+ "expiry" : {
71+ "StringValue" : str (expiry ),
72+ "DataType" : "Number" ,
73+ }
74+ },
7875 MessageBody = message .message .decode ("utf-8" ),
7976 MessageGroupId = message .task_name ,
8077 )
@@ -102,14 +99,20 @@ async def listen(self) -> AsyncGenerator[Union[bytes, AckableMessage], None]:
10299 while True :
103100 last_had_message = False
104101
105- for message in await asyncify (queue .receive_messages )():
102+ for message in await asyncify (queue .receive_messages )(
103+ MessageAttributeNames = [".*" ]
104+ ):
106105 try :
107106 if message .message_attributes :
108107 # if expiry was set as a message attribute, respect it
109- if expiry := message .message_attributes .get ("expiry" ):
110- diff = stamp () - expiry
111- if diff > 0 :
112- logger .debug (f"Message expired { diff } seconds ago. Skipping." )
108+ if expiry_typed := message .message_attributes .get ("expiry" ):
109+ expiry = int (expiry_typed .get ("StringValue" , 0 ))
110+ now = stamp ()
111+ if 0 < expiry < now :
112+ logger .warn (
113+ f"Message expired { now - expiry } seconds ago. Skipping."
114+ )
115+ await asyncify (message .delete )()
113116 continue
114117 except TypeError :
115118 # Ignore weird expiries. Not critical.
0 commit comments