Einer unserer Kunden ist auf ein reproduzierbares Problem gestoßen, als er ein lokales Discourse-Backup über die Admin-Oberfläche hochgeladen hat.
Der Backup-Uploader verwendet feste 5-MB-Blöcke (Chunks) und kann bei einer sufficiently schnellen Verbindung genügend Anfragen generieren, um das anwendungseigene Request-Rate-Limit von Discourse zu überschreiten. In diesem Fall gibt der Server HTTP 429 zurück, aber der Chunked-Uploader versucht 429-Antworten nicht erneut und beachtet den Retry-After-Header nicht. Infolgedessen schlägt der gesamte Backup-Upload fehl.
Nicht-2xx-Antworten werden in einen Fehler umgewandelt:
if (ev.target.status < 200 || ev.target.status >= 300) {
const error = new Error("Non 2xx");
error.source = ev.target;
reject(error);
return;
}
Die Retry-Logik lautet:
_shouldRetry(err) {
if (err.source && typeof err.source.status === "number") {
const { status } = err.source;
return (
status === 0 ||
status === 409 ||
status === 423 ||
(status >= 500 && status < 600)
);
}
return false;
}
HTTP 429 ist daher ausdrücklich nicht wiederholbar.
Eine einzige 429-Antwort reicht aus, damit das Chunk-Upload-Promise fehlschlägt, was schließlich upload-error für den gesamten Backup-Upload auslöst.
Auch wird der Retry-After-Response-Header nicht verarbeitet.
Ich habe dieses Thema aus dem Jahr 2021 gefunden, das ziemlich schnell in andere Bahnen gelenkt wurde, aber anscheinend exakt dasselbe Problem beschreibt.