Any way to run code all active sessions die, similar to on.exit() or session$onEnded() but globally?

32 views
Skip to first unread message

Dean Attali

unread,
Jun 21, 2017, 5:37:43 PM6/21/17
to Shiny - Web Framework for R
Suppose the 'pool' package did not exist, and I wanted to create a single database connection globally. I'd place the code to connect to the DB in global.R

Suppose I know the app will only have a few people at a time and queries are short and I'm happy with having one connection share between everyone.

What would be the correct way to disconnect from the database?

Dean Attali

unread,
Jun 21, 2017, 6:07:22 PM6/21/17
to Shiny - Web Framework for R
Actually, it looks like even with the pool package I still want an answer to this question :)

Given the following code:

# assumes you have credential info and table name in options()

library
(pool)
library
(DBI)
library
(shiny)

pool
<- dbPool(
  drv
= RMySQL::MySQL(),
  user
= options()$mysql_db$user,
  password
= options()$mysql_db$password,
  dbname
= options()$mysql_db$dbname,
  host
= options()$mysql_db$host
)

ui
<- fluidPage(
  numericInput
("nrows", "How many rows to show?", 10),
  tableOutput
("tbl")
)

server
<- function(input, output, session) {
  output$tbl
<- renderTable({
    query
<- paste0("SELECT * FROM ", options()$mysql_db$table, " LIMIT ",
                    as.integer(input$nrows)[1], ";")
    df <- dbGetQuery(pool, query)
    df
  })
}

shinyApp(ui, server)

Every time I run the app, a new pool is created, and the previous ones are not deleted. Running 

length(DBI::dbListConnections(RMySQL::MySQL()))

reveals that indeed every successive run accumulates another pool object, and after enough times, I get errors because of too many connections.

I assume this won't happen when the app is served via shiny server and is only happening when I'm running it interactively through rstudio, but I'd still like to know the proper place to disconnect.

Bárbara Borges

unread,
Jun 21, 2017, 6:25:36 PM6/21/17
to Shiny - Web Framework for R
Hi Dean,

You're right, there's currently no way of doing this. We're aware of this, and we're planning on addressing it at some point: https://github.com/rstudio/shiny/issues/1213 . However, as you've also pointed out, this is not a huge problem for deployed apps because, even though you leak database connections/pools, since the R process is terminated when all sessions are closed, those artifacts will be destroyed as well (even if not in the most graceful of ways). So, the bottom line is that this would be a nice to have feature that we plan to implement in the future, but we also don't think it's a huge priority because, in practice, things "work out."

What I'd recommend for now is:
  1. Don't worry about this for deployed apps.
  2. For interactive use at the console, just run `poolClose(pool)` (or whatever is appropriate) after you exit the app (you can just place this after the call to `shinyApp()` in your script and source the whole file -- instead of clicking "Run app").
Or you can always submit a PR :)

Barbara

Dean Attali

unread,
Jun 21, 2017, 6:34:19 PM6/21/17
to Shiny - Web Framework for R
Thanks, that answers the question in practical terms for this specific usecase.

I'm still wondering if there IS a way to properly implement an onexit-type of function for the more general case

Joe Cheng

unread,
Jun 22, 2017, 4:54:59 PM6/22/17
to Dean Attali, Shiny - Web Framework for R
I agree that this is really needed. There are lots of things we might do to mutate some global state that want to be un-done once the app is done running (or even if the app fails to completely launch).

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/0c98a54f-afc2-4d2f-9614-9a32417b3b5b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages