Hola !
Estamos generando un informe largo en PDF que toma alrededor de 3 minutos y lo exponemos a través de Plumber.
La conexión HTTP se cierra alrededor de 1 minuto 40 segundos (100 segundos).
Entonces tenemos el mensaje de error lógico porque el plomero intenta enviar datos a una conexión cerrada:
ERROR: [on_request_read] connection reset by peer
Creo que puede estar relacionado con el n. ° 12 y, por cierto, https://github.com/rstudio/httpuv/issues/49
¿Hay alguna manera de arreglar eso en Plumber? Puede ser enviando manualmente en Plumber algo así:
Keep-Alive: timeout=300
Connection: Keep-Alive
Pero en cualquier caso queremos evitar el #12
Atentamente,
emmanuel
Desafortunadamente, no estoy lo suficientemente familiarizado con las partes internas de httpuv para poder hablar de manera inteligente sobre por qué podría suceder esto.
Sin embargo, para dar un paso atrás, el patrón habitual al realizar este tipo de tareas de larga duración en otros sistemas es responder de inmediato a la solicitud entrante y luego iniciar el trabajo de forma asíncrona. El cliente obtiene una identificación en respuesta a la solicitud original y luego puede sondear para averiguar cuándo está completa.
Desafortunadamente, R tiene un solo subproceso, por lo que esto es un poco más complicado. Pero si estuviera lo suficientemente motivado, podría ver fork
en el proceso R (consulte los paquetes paralelos o multinúcleo) y luego generar el informe en una bifurcación del proceso, dejando el proceso principal disponible para responder a las solicitudes de API. (como clientes que están encuestando para ver si se genera su informe).
Hola,
Aquí, hemos optimizado nuestro código R para que en realidad no sea un problema. Pero el problema puede reaparecer en otros casos. Si encuentro una solución, volveré y la publicaré aquí.
En caso de que alguien encuentre este problema relevante: fork
ing funciona bastante bien y se hace fácilmente con el paquete parallel
.
parallel <- function() {
# Long running calculation here
print("Sleeping...")
Sys.sleep(10)
print("Finished.")
return(Sys.time())
}
#* <strong i="8">@get</strong> /parallel
parallelTest <- function() {
parallel::mcparallel(parallel())
return(TRUE)
}
Comentario más útil
En caso de que alguien encuentre este problema relevante:
fork
ing funciona bastante bien y se hace fácilmente con el paqueteparallel
.