Chunked-Backup-Uploader überschreitet das Discourse-Request-Limit

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.