如何在R Shiny中实现清理程序?

时间:2014-04-24 18:04:08

标签: r shiny

例如,我的闪亮应用可能会打开数据库连接

# server.R
db <- dbConnect("SQLite", DB_PATH)
shinyServer(
    ...  # things involving db
)

现在,当Shiny会话结束时,如何确保连接db正确关闭(通过dbDisconnect(db))?实际上,应该为连接到服务器的每个客户端执行清理,还是仅执行一次?

我担心多个用户一直连接到Shiny应用程序并断开连接,如果没有正确清理,他们将留下悬空的数据库连接。实际上,客户只需关闭浏览器就可以在没有警告的情况下断开连接。

4 个答案:

答案 0 :(得分:27)

执行此操作的正确方法是使用session$onSessionEnded指定执行清理的功能。例如,在server.R中:

cancel.onSessionEnded <- session$onSessionEnded(function() {
    dbDisconnect(db)
})

然后,您可以致电cancel.onSessionEnded撤消分配。

答案 1 :(得分:10)

预先存在的答案对我来说似乎不对。

    当每个用户断开连接时,
  • session$onSessionEnded可以关闭连接,但在原始问题中,所有用户只有一个连接。特别是在使用pool时,您不希望为每个用户启动/停止单独的连接。
  • on.exit直接运行,而不是等到服务器退出。

我认为正确的答案是使用onStophttps://shiny.rstudio.com/reference/shiny/latest/onStop.html)。

示例用法,来自文档:

library(shiny)
shinyApp(
  ui = basicPage("onStop demo"),

  server = function(input, output, session) {
    onStop(function() cat("Session stopped\n"))
  },

  onStart = function() {
    cat("Doing application setup\n")

    onStop(function() {
      cat("Doing application cleanup\n")
    })
  }
)

答案 2 :(得分:6)

Rstudio在6月份发表了一系列关于连接数据库的最佳实践的文章。简单的答案是使用池(请参阅herehere)。为简单起见,您需要定义一次池,它将处理和管理连接,根据需要打开和关闭它们。应用程序断开连接后,池将自动关闭所有连接。

不幸的是,池包不适用于SQL Server和ODBC。对于那种情况(或者如果你不想使用池),他们建议你在服务器函数 s 中使用on.exit。

例如:

getData <- reactive({
cnxn <- dbConnect(...)
on.exit(dbDisconnect(cnxn))

... # your stuff here
})

答案 3 :(得分:-1)

您可以在shinyServer函数定义中使用on.exit(dbDisconnect(db))