I have a function which sets some output in a shiny app upon a click of a button. Since this process takes some time I want to run it in background. I really like callr
package for this but I am facing some trouble implementing this in my current scenario.
I have created a small example to demonstrate my issue. First, an example which works without callr
.
library(shiny)
ui <- fluidPage(
actionButton("click", "click me!"),
textOutput("text")
)
server <- function(input, output, session) {
call_fun <- function(input, output) {
Sys.sleep(5)
output$text <- renderText("Output is generated")
}
observeEvent(input$click, {
call_fun(input, output)
})
}
shinyApp(ui, server)
Sys.sleep(5)
is to mimic a process that takes time.
Now I'm trying to implement the same with callr
. This is what I have.
library(shiny)
ui <- fluidPage(
actionButton("click", "click me!"),
textOutput("text")
)
server <- function(input, output, session) {
rv <- reactiveValues(callr = NULL)
call_fun <- function(input, output) {
Sys.sleep(5)
output$text <- shiny::renderText("Output is generated")
}
observeEvent(input$click, {
rv$callr <- callr::r_bg(function(input, output, call_fun) call_fun(input, output),
args = list(input, output, call_fun))
})
observe({
req(rv$callr)
cat('\nIn Observe')
if(rv$callr$is_alive()) {
invalidateLater(millis = 1000, session = session)
cat('\nProcessing')
}
else {
cat("\nDone")
}
})
}
shinyApp(ui, server)
I do get the "Done" in console but I don't see the text output on screen.
Any idea how to solve this?