I've been trying to understand how to do async programming in Shiny but I cannot get it to work.
In my mind the date should keep refreshing every second while I wait (ten seconds) for the plot to appear. However, this is not what happens. The main session is kept busy by the Sys.sleep()
.
Can somebody shine a light on where my understanding of the logic goes wrong?
(I made my own reprex following the manual.)
library(shiny)
library(future)
library(promises)
plan(multisession)
ui <- fluidPage(
shiny::selectInput("select", "select", choices = c("iris","mtcars")),
tableOutput("table")
)
server <- function(input,output,session) {
output$table<- renderTable(
{
select <- input$select
future_promise(
{
Sys.sleep(10)
get(select)
}
) %...>%
data.frame()
}
)
# check if session is not taken by expensive operation
observe(
{
invalidateLater(1000,session = session)
print(Sys.time())
}
)
}
shinyApp(ui,server)
Previously async in Shiny was only capable of not blocking other users. Now there is ExtendedTask()
though which can handle what you are trying to do. Here is is an example of how to use it:
library(shiny)
library(future)
library(promises)
plan(multisession)
ui <- fluidPage(
shiny::selectInput("select", "select", choices = c("iris","mtcars")),
tableOutput("table")
)
server <- function(input,output,session) {
get_data <- function(select){
Sys.sleep(5)
get(select)
}
task <- ExtendedTask$new(function(...){
future_promise(get_data(...))
})
observe({
task$invoke(input$select)
})
output$table <- renderTable(
task$result()
)
# check if session is not taken by expensive operation
observe(
{
invalidateLater(1000,session = session)
print(Sys.time())
}
)
}
shinyApp(ui,server)