У меня есть прецедент, где я визуализую операционные данные для приборной панели. Я бы хотел, чтобы это было так, что визуализация обновляется периодически, когда данные добавляются в базу данных. Логика, на мой взгляд, заключается в том, чтобы сначала проверить, равно ли количество строк в таблице реальной базы данных количеству строк в соответствующем фрейме данных в пределах R. Если да, тогда нет необходимости извлекать данные, если нет, то извлекать данные из база данных. То, что я хочу избежать, - это просто вытащить данные (фактическая таблица базы данных имеет более 5 миллионов строк) периодически, независимо от того, есть ли новые данные или нет.Странное поведение R Shiny reactiveValues () и invalidateLater()
Я создал подмножество данных here. Код ниже я написал как доказательство концепции, чтобы сначала обернуть мою голову тем, как invalidateLater()
и reactiveValues()
работают в R и как я могу их использовать. Он просто считывает количество строк в таблице базы данных и отображает их пользователю. Если количество строк изменяется, пользовательский интерфейс обновляется с новым количеством строк. Обратите внимание, что для воспроизведения вы можете поместить данные в базу данных, чтобы вы могли имитировать добавление и удаление строк, чтобы увидеть реакцию «приложения». Я использовал postgres и соединение ODBC. Если вы запустите код как есть, вы заметите, что когда строки добавляются в db, когда приложение выполняет проверку, пользовательский интерфейс (textOutput()
widget) выделяется на несколько секунд и, кажется, находится в состоянии медитации, прежде чем в итоге правильно отобразить новое количество строк. Это использует код, который первым проверяет, имеются различия в числах строк между базой данных и значения, сохраняемого в R.
Однако, если я закомментировать ту часть кода, проверьте различия (закомментируйте ниже блок)
sharedValues$data <- if(!is.null(sharedValues$data)){
if(nrow(sqlFetch(conn2,"test2")) == sharedValues$data){
return(sharedValues$data)
}
}
else{
sharedValues$data <- nrow(sqlFetch(conn2,"test2"))
return(sharedValues$data)
}
и вместо того, чтобы просто тянуть данные периодически, независимо, если есть изменения или нет (раскомментируйте линию)
#sharedValues$data <- nrow(sqlFetch(conn2,"test2"))
интерфейс реагирует великолепно, нет задержки (серого цвета текста виджета) и новое значение строки отображается на пользовательский интерфейс.
Мой вопрос заключается в том, что приводит к поведению «лаг-как» при запуске первой альтернативы (которая является желательной альтернативой) первой проверки изменений базы данных, прежде чем делать запрос на выборку с большой стоимостью), но когда код изменен на вытащить данные независимо от изменений базы данных (что кажется мне неэффективным), это отставание от поведения приводит к его уродливой голове? Весь код ниже:
library(shiny)
library(shinydashboard)
library(rCharts)
library(curl)
library(RODBC)
conn2 <- odbcConnect("postgres") # database connection object
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(),
dashboardBody(
fluidRow(
box(textOutput("text1"),width = 6)
)
)
)
server <- function(input, output, session) {
sharedValues <<- reactiveValues()
observe({
invalidateLater(30000,session)
cat("updating data...\n")
sharedValues$data <- if(!is.null(sharedValues$data)){
if(nrow(sqlFetch(conn2,"test2")) == sharedValues$data){
return(sharedValues$data)
}
}
else{
sharedValues$data <- nrow(sqlFetch(conn2,"test2"))
return(sharedValues$data)
}
#sharedValues$data <- nrow(sqlFetch(conn2,"test2"))
})
output$text1 <- renderText({
y <- sharedValues$data
return(y)
})
}
shinyApp(ui, server)
Любая помощь очень ценится.