Deliveries refused with 409 or 422 get three tries
Mastodon answers 422 when two first contacts from one actor race to create its account (ActiveRecord::RecordInvalid on the unique uri), and 409 while another worker holds its lock. A persona that followed two Mastodon accounts at once had one Follow refused that way; the job died on its first attempt and the persona waited on "requested" forever. Both answers are now retried twice on the usual backoff before they count as refusals. Found by the town (a village of 23 accounts on seven servers). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
128ff89426
commit
b9286c2c6e
2 files changed
+25
-2
No files matched your search
@@ -216,6 +216,11 @@ namespace PrivaPub.Federation.Outbox
|
||||
? JobOutcome.Defer(DateTime.UtcNow + Min(retryAfter.Value, TimeSpan.FromHours(6)), $"{status}")
|
||||
: JobOutcome.Retry($"{status}");
|
||||
}
|
||||
// Mastodon answers 422 when two first contacts from one actor race to create its account (RecordInvalid on the
|
||||
// unique uri) and 409 while another worker holds its lock: a Follow refused that way was lost for good, and the
|
||||
// persona waited on "requested" forever (found by the town). Both get a few tries before they count as refusals.
|
||||
if (status is 409 or 422 && job.Attempts < TransientRefusalAttempts)
|
||||
return JobOutcome.Retry($"{status} {response.ReasonPhrase}");
|
||||
if (status is >= 400 and < 500 && status != 408)
|
||||
{
|
||||
await _breaker.Succeeded(job.Host, token);
|
||||
@@ -239,6 +244,8 @@ namespace PrivaPub.Federation.Outbox
|
||||
}
|
||||
}
|
||||
|
||||
const int TransientRefusalAttempts = 3;
|
||||
|
||||
static TimeSpan Min(TimeSpan a, TimeSpan b) => a < b ? a : b;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user