我想定期检查输入文件并更新是否符合某些条件。
以下代码可以正常工作,但仅限于至少有一个会话处于活动状态。我的目标是更新 acc 数据帧,即使ShinyApp上没有活动会话。
因为加载数据集需要4-5分钟,并且在文件更新时过夜,而不是在第一个用户打开应用程序的早晨,这样做很棒。
observe({
invalidateLater(1000000, session)
m.acc <- file.info(accPath)
m.acc.mtime <- m.acc$mtime
# If no change in modtime, do nothing
if (acc.mtime == m.acc.mtime) {
print('no change in the accounts')
return(NULL)
} else {
acc.mtime = m.acc.mtime
s <- Sys.time()
acc <- read.csv(accPath)
l <- Sys.time()
time<- paste("Data refresh took:",l-s)
print(time)
}
})
暂时,我在主机上打开一个会话,但我想找出一个更好的方法。有什么建议吗?
答案 0 :(得分:0)
选项 1:reactivePoll
一个选项是 reactivePoll
。它具有三个相关设置:
1000000
的轮询间隔。acc.mtime != m.acc.mtime
。请原谅我用随机抽样来嘲笑业务逻辑。这个问题没有给我一个完整的 reprex 所需的所有细节。
library(shiny)
runApp(list(
ui = pageWithSidebar(
headerPanel("Hello Shiny!"),
# UI CODE
),
server = function(input, output, session) {
UpdateRequired <- function() {
sample.int(3, 1) # MOCKED CONDITION using a random number to get 66% update chance
}
dist <- reactivePoll(1000, session, UpdateRequired, function () {
### PUT HERE ANY CODE TO RE-READ YOUR FILE INSTEAD OF CREATING RANDOM NUMBERS
rnorm(input$obs) # MOCKED "File update": create random numbers instead
})
output$distPlot <- renderPlot({
hist( req(dist()) )
})
}
))
选项 2:reactiveFileReader
reactiveFileReader
甚至更适合这项工作。它“通过定期检查文件的上次修改时间来工作;如果它已更改,则重新读取该文件并使任何反应性依赖项无效”(引自手册)。所以,您不必自己做。
使用 reactiveFileReader(intervalMillis, session, filePath, readFunc)
并为 readFunc
提供函数。 “用于读取文件的函数;必须期望第一个参数是要读取的文件路径。此函数的返回值用作反应文件读取器的值”。