在R Shiny包中使用`pool`

问题描述

如何在结构像程序包的R Shiny应用程序中实现pool对象的使用?

我已经整理好了哈德利·威克汉姆(Hadley Wickham)在“精通闪亮”中描述的软件包according to the layout

├── DESCRIPTION
├── NAMESPACE
├── R
  ├── app.R
  ├── modules.R
├── app.R
├── inst
└── tests

我的Shiny应用程序位于R/app.R中,该函数包装在名为callApp()的函数中。文件./app.R只需调用callApp()

文件modules.R实际上代表了许多.R文件,这些文件包含构成我的Shiny应用程序的各种功能和模块。我的Shiny应用程序看起来像:

callApp <- function() {
  pool <- pool::dbPool(
    RMySQL::MySQL(),dbname = config::get("db_name"),host = config::get("db_host"),username = Sys.getenv("DB_USERNAME"),password = Sys.getenv("DB_PASSWORD")
  )

  onStop(function() {
    pool::poolClose(pool)
  })

  header <- dashboardHeader(
    title = "title"
  )

  sidebar <- dashboardSidebar(
      ....
  )

  body <- dashboardBody(
      ....
  )

  ui <- dashboardPage(header,sidebar,body)

  server <- function(input,output,session) {
    modulefunction_server("module1")
    modulefunction_server("module2")
  }

  shiny::shinyApp(ui,server)
}

如您所见,我using the pool package正在连接到MySQL数据库并检索我的数据。如pool文档中所述,我已将app.R放在主要pool的顶部。但是,我遇到的问题与我的功能modulefunction_server()有关:

modulefunction_server <- function(id) {

  shiny::moduleServer(id,function(input,session) {

      dates <- datepicker_server("datepicker1")

      data <- getData(startDate = dates$date_from(),endDate = dates$date_to())

   
      output$report <- DT::renderDT({
        make_table(data)
      })
   })
 }

实际上,函数getData()需要pool对象。 getData()存储在我的modules.R文件中:

getData <- function(startDate,endDate) {
  sql <- getSQLFromFile(system.file("sql","query.sql",package = "mypackage"))
  query <- DBI::sqlInterpolate(pool,sql,startDate = startDate,endDate = endDate)
  DBI::dbGetQuery(pool,query)
}

运行应用程序时,出现错误:

 error in evaluating the argument 'conn' in selecting a method for function 'sqlInterpolate': object 'pool' not found

为Shiny应用程序中的所有函数提供对pool的访问的推荐方法是什么?我想我可以将pool作为参数传递给每个函数,但是当尝试通过嵌套在复杂的Shiny应用程序中的5、10或15个函数从pool检索数据时,这变得非常混乱和混乱。

更新:

我找到了this related GitHub issue,并试图实施该解决方案:

我已将pool移到globals.R文件中。我在globals.R的开头输入app.R,将onStop()函数移到shinyApp()函数中:

callApp <- function() {
  source("R/globals.R")

  onStop(function() {
    pool::poolClose(pool)
  })

  header <- dashboardHeader(
    title = "title"
  )

  sidebar <- dashboardSidebar(
      ....
  )

  body <- dashboardBody(
      ....
  )

  ui <- dashboardPage(header,session) {
    modulefunction_server("module1")
    modulefunction_server("module2")
  }

  shiny::shinyApp(ui = ui,server = server,onStart = function() {
    onStop(function() {
       pool::poolClose(pool)
     })
  })
}

不幸的是,尽管这使pool对所有功能可见,但是每次重新构建程序包时,我仍然留下Warning in (function (e) : You have a leaked pooled object

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)