Il caricatore di backup a blocchi supera il limite di frequenza delle richieste di Discourse

Uno dei nostri clienti ha riscontrato un problema riproducibile durante il caricamento di un backup locale di Discourse tramite l’interfaccia di amministrazione.

Il caricatore di backup utilizza chunk fissi da 5 MB e, su una connessione sufficientemente veloce, può generare un numero di richieste tale da superare il limite di frequenza delle richieste a livello di applicazione di Discourse stesso. Quando ciò accade, il server restituisce un HTTP 429, ma il caricatore a chunk non ripete le risposte 429 né rispetta l’intestazione Retry-After. Di conseguenza, l’intero caricamento del backup fallisce.

Le risposte non 2xx vengono convertite in un errore:

if (ev.target.status < 200 || ev.target.status >= 300) {
  const error = new Error("Non 2xx");
  error.source = ev.target;
  reject(error);
  return;
}

La logica di ripetizione è:

_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;
}

L’HTTP 429 non è quindi esplicitamente ripetibile.

Una singola risposta 429 è sufficiente perché la promessa di caricamento a chunk fallisca, innescando infine upload-error per l’intero caricamento del backup.

Non c’è anche alcun trattamento dell’intestazione di risposta Retry-After.


Ho trovato questo argomento del 2021 che si è deragliato abbastanza rapidamente, ma sembra essere esattamente la stessa cosa