Uno de nuestros clientes se encontró con un problema reproducible al subir una copia de seguridad local de Discourse a través de la interfaz de administración.
El cargador de copias de seguridad utiliza fragmentos fijos de 5 MB y, con una conexión lo suficientemente rápida, puede generar suficientes solicitudes para exceder el límite de tasa de solicitudes a nivel de aplicación propio de Discourse. Cuando ocurre esto, el servidor devuelve un HTTP 429, pero el cargador por fragmentos no reintenta las respuestas 429 ni respeta la cabecera Retry-After. Como resultado, la carga completa de la copia de seguridad falla.
Las respuestas no 2xx se convierten en un error:
if (ev.target.status < 200 || ev.target.status >= 300) {
const error = new Error("Non 2xx");
error.source = ev.target;
reject(error);
return;
}
La lógica de reintento es:
_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;
}
Por lo tanto, el HTTP 429 no es explícitamente reintentable.
Una sola respuesta 429 es suficiente para que la promesa de carga por fragmentos falle, lo que finalmente desencadena upload-error para toda la carga de la copia de seguridad.
Tampoco hay ningún manejo de la cabecera de respuesta Retry-After.
Encontré este tema de 2021 que se desvió bastante rápido, pero parece ser exactamente lo mismo