2014-04-24 11 views
11

例如,我有光澤的應用程序可能會打開一個數據庫連接如何在R Shiny中實現清理程序?

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

現在,如何確保連接db正確關閉(通過dbDisconnect(db))當閃亮的會話結束?事實上,應該爲連接到服務器的每個客戶端執行清理,還是隻執行一次?

我只是擔心,隨着多個用戶連接和斷開連接到Shiny應用程序,他們會留下懸掛的數據庫連接,如果不正確清理。事實上,客戶只需關閉瀏覽器即可斷開連接而無需警告。

回答

24

正確的方法是使用session$onSessionEnded來指定一個執行清理的函數。例如,在server.R:

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

你可以調用cancel.onSessionEnded撤消分配。

+0

這適用於我。如果你只需要在退出時調用函數,那麼你不需要給它起個名字。 – sdgfsdh

+0

這是如何工作在最新版本的閃亮,你有一個腳本(例如,app.R與ui和服務器定義在其中)。連接是否超出服務器功能定義或內部?如何在兩種情況下適當斷開連接? –

+0

答案在這裏:https://shiny.rstudio.com/articles/pool-basics.html在ui和服務器功能之外使用'pool'創建一個連接 –

0

您可以使用on.exit(dbDisconnect(db))裏面的shinyServer函數定義。

+1

在這種情況下,是否也應該把'分貝< - 數據庫連接( 「SQLite的」,DB_PATH)''內shinyServer'?我假定'shinyServer'內的任何內容都是每個客戶端執行一次,'shinyServer'之外的任何內容只能由服務器執行一次。 – mchen

+0

我不認爲這有什麼區別。在任何情況下,它都會爲每個客戶端連接執行一次,無論它是否在'shinyServer'定義中。 – tmpname12345

+2

@ tmpname12345,我測試了它,但實際上它不起作用:在啓動runApp時,shinyServer將被調用一次。在這種情況下,連接將在第一次運行中關閉,並且在閃亮的會話期間不會持續。 –

4

Rstudio在6月份發佈了一系列關於連接數據庫的最佳實踐的文章。簡單的答案是使用池(請參閱herehere)。爲了簡單起見,您定義了一次池,它將處理和管理連接,根據需要打開和關閉連接。一旦應用程序斷開連接,池將自動關閉所有連接。

不幸的是,該池包不適用於SQL Server和ODBC。對於這種情況(或者如果你不想使用池),他們建議在服務器功能s內使用on.exit。

例如:

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

... # your stuff here 
}) 
4

預先存在的答案,似乎沒有我的權利。當每個用戶斷開連接,但在原來的問題只有一個所有用戶連接

  • 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") 
    }) 
    } 
) 
相關問題