rstudio / shiny-server

Host Shiny applications over the web.
https://rstudio.com/shiny/server
Other
712 stars 290 forks source link

Apps using reticulate don't exit on shiny-server stop/restart #494

Closed jcheng5 closed 3 years ago

jcheng5 commented 3 years ago

Install the following app under a subdirectory of /srv/shiny-server/:

app.R

library(shiny)

reticulate::source_python("test.py")

ui <- "Hello"

server <- function(input, output, session) {
}

shinyApp(ui, server)

test.py

print(1)

Prerequisites

Your run_as user needs the reticulate R package installed, and a reticulate-compatible python environment (running reticulate::install_miniconda() is what I did).

Repro instructions

  1. Run pgrep R before launching Shiny Server, hopefully there are no processes but if there are take note of them.
  2. Launch Shiny Server.
  3. Load the above app.
  4. Do pgrep R again, see the new pid that has appeared.
  5. Without closing the browser, stop Shiny Server.
  6. Do pgrep R again, see that the new pid has not disappeared; i.e., the R process has leaked!

Explanation

This happens because Shiny Server's normal strategy for stopping R processes is by sending SIGINT, waiting 20 seconds, and sending SIGTERM if necessary. This works fine when the server is running normally. But during shutdown, SIGINT is sent but there isn't time for 20 seconds to pass to follow up with SIGTERM if necessary. In this case, something about using reticulate/python causes SIGINT signals to be ignored by the R process; but SIGTERM would have worked.

The fix is that when shiny-server is shutting down, it should be less polite and just send SIGTERM. (Note that there's no real-world evidence that SIGTERM is worse for Shiny apps than SIGINT, when I wrote this code many years ago it just seemed the right thing to do to simulate a user hitting Ctrl+C, so any tryCatch/finally could run--but RStudio Connect just sends SIGTERM and it doesn't seem to have been a problem for anyone.)