Salut !
Nous générons un long rapport en PDF qui prend environ 3 minutes et nous l'exposons via Plumber.
La connexion HTTP se ferme environ 1 minute 40 secondes (100 secondes).
Nous avons donc le message d'erreur logique car le plombier essaie d'envoyer des données à une connexion fermée :
ERROR: [on_request_read] connection reset by peer
Je pense que cela peut être lié à # 12 et d'ailleurs https://github.com/rstudio/httpuv/issues/49
Il existe un moyen de résoudre ce problème dans Plumber ? Peut-être en envoyant manuellement dans Plumber quelque chose comme ça :
Keep-Alive: timeout=300
Connection: Keep-Alive
Mais dans tous les cas on veut éviter le #12
Cordialement,
Emmanuel
Malheureusement, je ne connais pas assez les rouages de httpuv pour pouvoir expliquer intelligemment pourquoi cela pourrait arriver.
Pour revenir en arrière, cependant, le schéma habituel lors de l'exécution de ce type de tâches de longue durée dans d'autres systèmes consiste à répondre immédiatement à la demande entrante, puis à lancer le travail de manière asynchrone. Le client obtient un identifiant en réponse à la demande d'origine, puis peut l'interroger pour savoir quand il est terminé.
Malheureusement, R est monothread donc c'est un peu plus compliqué. Mais si vous étiez suffisamment motivé, vous pourriez regarder fork
ing le processus R (voir les packages parallèles ou multicœurs) puis générer le rapport dans un fork du processus, laissant le processus parent disponible pour répondre aux requêtes API (comme les clients qui interrogent pour voir si leur rapport est généré).
Salut,
Ici, nous avons optimisé notre code R donc ce n'est pas un problème en fait. Mais le problème peut revenir dans d'autres cas. Si j'ai trouvé une solution, je reviendrai et je la publierai ici.
Juste au cas où quelqu'un trouverait ce problème pertinent : fork
ing fonctionne assez bien et se fait facilement avec le package 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)
}
Commentaire le plus utile
Juste au cas où quelqu'un trouverait ce problème pertinent :
fork
ing fonctionne assez bien et se fait facilement avec le packageparallel
.