@@ -1,7 +1,8 @@
1import { Queue, type Message } from "./queue";
1import { Queue, type Message } from "./queue"; 2import { deliver } from "../delivery";
2import { deliver } from "../delivery"; 3−import { backoff } from "./retry"; 3+import { backoff, MAX_ATTEMPTS } from "./retry"; - LM
Leo Marchetti2h
Should MAX_ATTEMPTS come from the endpoint's retry policy? Ops will want to tune it for the noisy integrations.
- SW
Sam Whitfield1h
Fair. I'd keep the constant as the default and read endpoint.retryPolicy in a follow-up, so this one stays small.
4+import { deadLetter } from "./dead-letter"; 4import { metrics } from "../metrics";
5import { metrics } from "../metrics"; 6const queue = new Queue("webhooks");
7const queue = new Queue("webhooks"); ⋯@@ -38,15 +39,31 @@ export async function consume(batchSize = 50)
38export async function consume(batchSize = 50) {
39export async function consume(batchSize = 50) { 39 const messages = await queue.receive(batchSize);
40 const messages = await queue.receive(batchSize); 41 for (const message of messages) {
42 for (const message of messages) { 43+ await handle(message); 43− await deliver(message.body); 44− await queue.ack(message); 46− await queue.retry(message, backoff(message.attempts)); 50 metrics.gauge("webhooks.lag", await queue.lag());
46 metrics.gauge("webhooks.lag", await queue.lag()); 49+async function handle(message: Message) { 51+ await deliver(message.body); 52+ await queue.ack(message); 54+ if (message.attempts + 1 >= MAX_ATTEMPTS) { 55+ // Park it so one bad payload can't hold up the partition. 56+ await deadLetter.put(message, error); 57+ await queue.ack(message); 58+ metrics.increment("webhooks.dead_lettered"); 61+ await queue.retry(message, backoff(message.attempts));