Le téléversement de sauvegarde par segments dépasse la limite de débit des requêtes Discourse

L’un de nos clients a rencontré un problème reproductible lors de l’envoi d’une sauvegarde Discourse locale via l’interface d’administration.

L’outil d’envoi de sauvegardes utilise des blocs fixes de 5 Mo et, sur une connexion suffisamment rapide, peut générer suffisamment de requêtes pour dépasser la limite de taux de requêtes au niveau de l’application de Discourse elle-même. Dans ce cas, le serveur renvoie un HTTP 429, mais l’outil d’envoi par blocs ne réessaie pas les réponses 429 et ne respecte pas l’en-tête Retry-After. En conséquence, l’envoi complet de la sauvegarde échoue.

Les réponses non 2xx sont converties en erreur :

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

La logique de réessai est la suivante :

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

Le HTTP 429 n’est donc explicitement pas réessayable.

Une seule réponse 429 suffit pour que la promesse d’envoi par blocs échoue, déclenchant éventuellement upload-error pour l’envoi complet de la sauvegarde.

Il n’y a également aucune gestion de l’en-tête de réponse Retry-After.


J’ai trouvé ce sujet de 2021 qui a déraillé assez rapidement, mais qui semble être exactement le même problème