Функция R Shiny Value не запускается в reactivePoll

Я использую reactivePoll, чтобы обновить свою блестящую панель инструментов. Когда я впервые запускаю приложение, оно работает нормально. Я дал интервал времени в 1 минуту для обновления данных. Через 1-ю минуту данные обновятся, как и ожидалось. Со следующей минуты функция проверки запускается каждую минуту, но функция значения не запускается, и я не получаю последние данные.

app.R

 library(shiny)
 library(shinythemes)
 library(shinyWidgets)
 library(shinydashboard)
 library(shinycssloaders)
 library(RPostgreSQL)
 library(pool)
 library(config)
 library(plotly)
 library(data.table)

Sys.setenv(R_CONFIG_ACTIVE = "xyz")
config <- config::get()

pool <- dbPool(
drv = dbDriver("PostgreSQL"),
host = config$host,
dbname = config$dbname,
port = config$port,
user = config$user,
password = config$password
)

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

get_data <- function(pool) {
abc <- dbGetQuery(pool,"SELECT * FROM tablename") #Query to pull data
return(abc)
}
abc <- get_data(pool = pool)

ui <- dashboardPage(
dashboardHeader(
title = 'Dashboard'
),
dashboardSidebar(
sidebarMenu(
  menuItem("pqr", tabName = "pqrs")
)
),
dashboardBody(
tabItems(
  tabItem(
    tabName = 'pqrs',
    hemaTab("pqr",abc = abc)
)
)
)
)

server <- function(input, output, session) {
pollData <- reactivePoll(60000, session,
                         checkFunc = function() {
                           print("Entered Check")
                           Sys.time()
                           print(Sys.time())
                         },
                         valueFunc = function() {
                           print("Entered value")
                           get_data(pool)
                         }
 )
 order(input, output, session, data = pollData())
 }

 shinyApp(ui = ui, server = server)

pqrs.R

pqrs <- function(id, label = "pqr",pqrs) {
ns <- NS(id)
tabPanel('pqr',
       tabsetPanel(
       tabPanel('Downloads',
                fluidPage(
                fluidRow(
                  column(12,
                         DT::dataTableOutput("table")
                  )
                )
                )
       )
       )
  )
  }

order <- function(input, output, session, data) {
downloaddata <- reactive({
setDT(data) 
})
output$table <- DT::renderDataTable( DT::datatable({
downloaddata()
})
)
}

I get the following result after running the app
"Entered Check"
[1] "2018-12-20 09:53:06 EST"
[1] "Entered Check"
[1] "2018-12-20 09:53:07 EST"
[1] "entered value"
After 1 minute the dashboard gets refreshed and I get the following 
result
[1] "Entered Check"
[1] "2018-12-20 09:54:07 EST"

Со следующей минуты приборная панель НЕ обновляется, но запускается функция проверки и отображается время.


person sk8    schedule 20.12.2018    source источник


Ответы (2)


tl; dr: попробуйте поместить функцию order(), которая вызывает poolData(), внутрь observe() функции

Я считаю, что проблема связана с тем, что reactivePoll, вопреки тому, как он работает, для правильного функционирования необходимо вызывать внутри реактивной среды.

Когда я запускаю программу ниже, у меня такая же проблема, как и у вас:

library(shiny)
ui <- fluidPage(
    mainPanel(
        verbatimTextOutput('text')
    )
)

server <- function(input, output, session) {
    pollData <- reactivePoll(600,session,
                             checkFunc = function() {
                                 print("Entered Check")
                                 Sys.time()
                                 print(Sys.time())
                             },
                             valueFunc = function() {
                                 print("entered value")
                                 return('x')
                             }
    )
    ord <- function(data) {
        print(data)
    }

    ord(isolate(pollData()))    # 1: Only triggers once
    # observe(ord(pollData()))  # 2: Triggers every time
}
shinyApp(ui = ui, server = server)

[1] "Entered Check"
[1] "2018-12-20 09:39:35 PST"
[1] "entered value"
[1] "x"
[1] "Entered Check"
[1] "2018-12-20 09:39:35 PST"
[1] "Entered Check"
[1] "2018-12-20 09:39:36 PST"
...

Но если я использую приведенный выше Второй способ (заключая вызов ord в функцию observe), он будет работать так, как ожидалось:

[1] "Entered Check"
[1] "2018-12-20 09:41:50 PST"
[1] "Entered Check"
[1] "2018-12-20 09:41:50 PST"
[1] "entered value"
[1] "x"
[1] "Entered Check"
[1] "2018-12-20 09:41:50 PST"
[1] "entered value"
[1] "x"

Я предполагаю, что происходит то, что reactivePoll работает как любое другое reactive* выражение: когда оно вызывается, оно проверяет, не признано ли оно недействительным. Если это не так, возвращается сохраненное значение; если да, то он запускается снова и возвращает обновленное значение.

Я думаю, что происходит следующее: когда checkFunc обнаруживает изменение, он не сообщает valueFunc о запуске напрямую, он просто делает недействительным reactive*. Как только он признан недействительным, valueFunc запускается при его вызове. Если вы никогда его не вызываете (поскольку вас интересуют только побочные эффекты), valueFunc не запускается.


В вашем случае я думаю (по какой-то причине) реактивная среда, созданная shinydashboard функциями, похожа на первый вариант: это достаточно похоже на реактивную среду, что она может получить доступ к значению функции reactivePoll, но она не запускает valueFunc. Окружив функцию order функцией observe*, вы продолжите проверять и вызывать функцию.

person divibisan    schedule 20.12.2018
comment
Я вызываю pollData (). Это не работает должным образом. Я не упоминал об этом раньше. Я включил это в код сейчас. Спасибо. - person sk8; 20.12.2018
comment
@ user10596599 Что это за выражение order и почему в нем есть input, output и session? Кроме того, вы должны вызывать reactive-выражения из реактивного контекста (т.е. внутри render*, observe*, isolate или reactive*). Добавленная вами строка не запускается, поэтому у меня нет возможности ее проверить. Пожалуйста, сделайте ваш пример воспроизводимым. - person divibisan; 20.12.2018
comment
Я работаю с блестящей приборной панелью. Вместо того, чтобы писать код в функции сервера, я использую функцию заказа и вызываю ее там, где это необходимо. Да, я вызываю все реактивные выражения из реактивных контекстов. - person sk8; 20.12.2018
comment
@ user10596599 Я думаю, вам действительно нужно предоставить минимальный воспроизводимый пример вашей проблемы. В опубликованном вами примере poolData() не вызывается из реактивного контекста, но без минимального воспроизводимого примера это невозможно чтобы действительно увидеть, что происходит - person divibisan; 20.12.2018
comment
Спасибо. Я отредактировал сообщение, включив в него полный код. - person sk8; 20.12.2018

Это сработало для меня при автообновлении при изменении базовых данных в базе данных postgres:

library(shiny)

# Define UI for application that draws a histogram
ui <- fluidPage(

 # Application title
 titlePanel("Auto Update DB Table Viewer"),

 # Table Viewer
 DT::dataTableOutput("my_drugs_dt")
)

# Define server logic
server <- function(input, output) {
 library(magrittr)
 library(dplyr)

 # Get DB auth token
 rdshost <- "db.xxxxx.us-xxxx-x.rds.amazonaws.com"
 username <- "my_user_name"
 region <- "us-xxxx-x"
 token <- reactiveValues(rds_token = system(paste0("aws rds generate-db-auth-token --hostname ", rdshost, " --port 5432 --username ", username, " --region ", region), intern = TRUE))

 # Establish DB connection
 myPool <- pool::dbPool(drv = RPostgres::Postgres(),
                      dbname="sengine-data",
                      host=rdshost,
                      user= username,
                      password = isolate(token$rds_token),
                      bigint = "numeric")
onStop(function() { pool::poolClose(myPool) })

# Pull the data from DB
# Note: using the changelog timestamp from the database would be the best way to do checkFunc.  
#helpful: https://www.postgresql.org/docs/11/functions-info.html
#or this one: SELECT * FROM pg_last_committed_xact() https://www.tutorialdba.com/2017/11/postgresql-commit-timestamp-tracking.html
#This is how to modify the parameter in rds: https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-query-logging/
mysource_drugs <- reactivePoll(intervalMillis = 1000, 
                               session = NULL,
                               checkFunc = function(){
                                   conn <- pool::poolCheckout(myPool)
                                   mod_stamp <- RPostgres::dbGetQuery(conn, "SELECT timestamp FROM pg_last_committed_xact()")
                                   pool::poolReturn(conn)
                                   return(mod_stamp)
                               }, 
                               valueFunc = function(){
                                   myPool %>%
                                       dplyr::tbl("drugs") %>%
                                       dplyr::collect()
                               }
)
output$my_drugs_dt <- DT::renderDataTable({
    mysource_drugs()
})
}

# Run the application 
shinyApp(ui = ui, server = server)
person Drwhit    schedule 24.09.2020