SqsTransport — AWS SQS FIFO (native fit)¶
AWS SQS FIFO gives the transport’s whole invariant for free, so this is the thinnest backend.
A FIFO queue’s MessageGroupId is the per-group exclusivity (SQS will not deliver another
message of a group while one is in flight), and the receive visibility timeout is the lease.
There is no lock table and no ready-index — AWS runs the exclusivity. Works against real SQS or
LocalStack (no AWS account) by pointing endpoint_url at it; boto3 is an optional extra.
It’s the all-AWS partner of DynamoDBStore.
No data model of our own¶
There is no schema — the queue is the SQS FIFO queue itself. create(...) ensures the queue
exists (create_queue(QueueName, Attributes={"FifoQueue": "true"}), appending .fifo to the name
if needed). The Lease’s handle is the SQS ReceiptHandle returned by receive_message (its
token).
The mapping¶
publish(group_id, event):
send_message(QueueUrl, MessageBody=event_json,
MessageGroupId=group_id, # the per-group exclusivity key
MessageDeduplicationId=uuid()) # unique per send (fan-out reuses event ids)
claim(worker_id, visibility):
receive_message(MaxNumberOfMessages=1,
VisibilityTimeout=int(visibility), # the lease: hidden from others until it elapses
WaitTimeSeconds=wait, # long-poll
AttributeNames=["MessageGroupId"])
-> Lease(group_id=msg.Attributes.MessageGroupId, event=msg.Body, token=msg.ReceiptHandle)
ack(lease): delete_message(QueueUrl, ReceiptHandle=lease.token) # remove it
nack(lease, delay=0): change_message_visibility(ReceiptHandle=lease.token,
VisibilityTimeout=int(delay)) # 0 = available now
close(): the boto3 client
Exclusivity & FIFO are AWS’s: within a
MessageGroupId, messages are delivered in order and only one is in flight at a time — exactly harel’s single-active-consumer-per-group invariant, natively.The lease is the visibility timeout: a received message is hidden for
VisibilityTimeoutseconds; if the worker dies (nodelete), it reappears — crash recovery, AWS-managed.MessageDeduplicationIdis a fresh uuid per send (NOT the event id): a fan-out re-uses event ids across its children, and SQS FIFO would dedupe identical dedup-ids within the 5-minute window, so a per-send uuid keeps every publish distinct.nack / park maps to
change_message_visibility:delay>0re-hides the message fordelayseconds (the park the control plane uses for a suspended group);delay=0makes it available immediately (retry).No priority. SQS FIFO has no per-group priority and
receive_messagecan’t filter by one, soSqsTransportrejectspublish(..., priority>0)andclaim(..., min_priority>0)with a clear error (fail-fast) rather than silently dropping them — a priority-routed worker (high_ratio>0) would otherwise be a no-op on SQS. Round-robin fairness across groups is still provided natively byMessageGroupIddelivery. Use another transport for priority routing.
Async twin¶
AsyncSqsTransport mirrors this over native-async aioboto3/aiobotocore — the same
send/receive/delete/change_visibility, every call awaited.
When to pick it¶
A fully serverless, no-server AWS stack — pair it with DynamoDBStore. One
caveat worth knowing: SQS can’t purge or prioritise a queue, which is why harel’s cooperative
cancel drains the backlog as no-ops rather than relying on a queue jump (see the
control plane). See the transports hub and
distribution.