Привет !
Мы создаем длинный отчет в формате PDF, который занимает около 3 минут, и мы предоставляем его через Plumber.
HTTP-соединение закрывается примерно через 1 минуту 40 секунд (100 секунд).
Итак, у нас есть логическое сообщение об ошибке, потому что сантехник пытается отправить данные по закрытому соединению:
ERROR: [on_request_read] connection reset by peer
Я думаю, что это может быть связано с № 12 и, кстати, https://github.com/rstudio/httpuv/issues/49 .
Есть ли способ исправить это в сантехнике? Может быть, отправив вручную в Plumber что-то вроде этого:
Keep-Alive: timeout=300
Connection: Keep-Alive
Но в любом случае мы хотим избежать #12
С наилучшими пожеланиями,
Эммануэль
К сожалению, я недостаточно знаком с внутренностями httpuv, чтобы разумно говорить о том, почему это может произойти.
Однако, чтобы сделать шаг назад, обычный шаблон при выполнении таких долгоживущих задач в других системах заключается в немедленном ответе на входящий запрос, а затем асинхронном запуске работы. Клиент получает некоторый идентификатор в ответ на исходный запрос, а затем может опросить его, чтобы узнать, когда он будет завершен.
К сожалению, R является однопоточным, так что это немного сложнее. Но если вы были достаточно мотивированы, вы могли бы посмотреть на fork
процесс R (см. параллельные или многоядерные пакеты), а затем сгенерировать отчет в ответвлении процесса, оставив родительский процесс доступным для ответа на запросы API. (например, клиенты, которые проводят опрос, чтобы узнать, сгенерирован ли их отчет).
Привет,
Здесь мы оптимизировали наш R-код, так что на самом деле это не проблема. Но проблема может вернуться в других случаях. Если я найду решение, я вернусь и опубликую его здесь.
На всякий случай, если кто-то найдет эту проблему актуальной: fork
ing работает довольно хорошо и легко выполняется с пакетом 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)
}
Самый полезный комментарий
На всякий случай, если кто-то найдет эту проблему актуальной:
fork
ing работает довольно хорошо и легко выполняется с пакетомparallel
.