Queue, retries & DLQ
For the SQS/DLQ infrastructure itself — queue configuration, retention, the redrive policy — see AWS resources and Data flow & failure modes. This page covers the ingestion-side mechanics: what actually goes on the queue, how ordering is decided, and how stockInboundProcess decides whether a failure gets retried at all.
What's actually in a message
stockInboundQueue doesn't put the CSV, or even a summary of it, on the queue — just a pointer:
const message: StockMessage = {
bucket: bucketName,
key: objectKey,
eventName: record.eventName
};stockInboundProcess re-fetches the actual file from S3 itself when it picks the message up. The queue is a work-item handoff, not a data-transport mechanism.
Ordering: scoped to one provider and one dealer, not global
Every send sets an explicit MessageGroupId, built at send time:
const provider = objectKey.split('/')[0];
const fileName = objectKey.split('/').pop() || '';
const dealerId = extractDealerIdFromFilename(fileName);
const messageGroupId = `${provider.trim()}/${dealerId.trim()}`;FIFO ordering only holds within one provider/dealerId pair. Two files from the same dealer are guaranteed to process in the order they were sent; files from different dealers, or different providers, process concurrently with no ordering relationship to each other at all. This is a deliberate trade — a dealer's own sequence of updates has to stay correct, but there's no reason to serialise unrelated dealers behind each other.
MessageDeduplicationId is a fresh randomUUID() on every send, not derived from the object key or file content — so SQS's content-based dedup isn't actually doing any deduplication here; every message is unique by construction, dedup or not.
Not every failure is treated as retryable
stockInboundProcess splits failures into two categories, and only one of them ever reaches the DLQ:
The handler splits failures into two categories, and only one of them ever reaches the DLQ:
| Trigger | What happens | |
|---|---|---|
| Structural failure | An uncaught exception — a malformed SQS message body, an unexpected error inside processing | Added to batchItemFailures → SQS retries the message → after 3 attempts, DLQ |
| Known content failure | processStock() returns success: false with a recognised message (empty CSV, file not found) | Logged, a CloudWatch metric (STOCK_CSV_EMPTY / STOCK_CSV_NOT_FOUND) is emitted, message is acknowledged — no retry, never reaches the DLQ |
A genuinely empty or already-deleted dealer file is a silent skip-with-metric, not a retry candidate — retrying it three times would never produce a different outcome, so it isn't retried at all.
There's no DLQ redrive tooling in this repo
If a message does land in the DLQ, there's currently no script, CLI command, or runbook here for inspecting or redriving it. That's a real gap, not an oversight in this documentation — if you need to recover a DLQ'd message today, it's a manual AWS console/CLI operation against the queue directly, not a scripts/ tool this repo provides.