rstudio / shiny

Easy interactive web applications with R
https://shiny.posit.co/
Other
5.37k stars 1.87k forks source link

Feature Request: Documentation and Examples for Shared Extended Tasks Across Users #4120

Closed WickM closed 1 month ago

WickM commented 1 month ago

In the Shiny Non-blocking Tasks article, it's mentioned that you might want to share an extended task across all visitors, allowing any user to invoke the task and making the results visible to all. This suggests that such a task should be declared at the top level of the app.R file, outside of any function. However, there is no documentation or examples provided on how to correctly implement this.

I am particularly struggling with understanding how to bind these global objects to inputs. While I understand that the task should be declared at the top level of app.R, it's unclear how to connect this shared global object to Shiny inputs, allowing the app to react to changes and updates from multiple users.

Could you provide an Example code snippets demonstrating this setup, particularly how to bind these global objects to Shiny inputs.

gadenbuie commented 1 month ago

Here's an example, taken from the example in the linked article. I moved the ExtendedTask definition for the sum_values task out of the server function, but then called bind_task_button(sum_values, "btn") inside the server function.

library(shiny)
library(bslib)
library(future)
library(promises)
future::plan(multisession)

ui <- page_fluid(
  p("The time is ", textOutput("current_time", inline=TRUE)),
  hr(),
  numericInput("x", "x", value = 1),
  numericInput("y", "y", value = 2),
  input_task_button("btn", "Add numbers"),
  textOutput("sum")
)

sum_values <- ExtendedTask$new(function(x, y) {
  future_promise({
    Sys.sleep(5)
    x + y
  })
})

server <- function(input, output, session) {
  output$current_time <- renderText({
    invalidateLater(1000)
    format(Sys.time(), "%H:%M:%S %p")
  })

  bind_task_button(sum_values, "btn")

  observeEvent(input$btn, {
    sum_values$invoke(input$x, input$y)
  })

  output$sum <- renderText({
    sum_values$result()
  })
}

shinyApp(ui, server)

The result is a linked, global task.

https://github.com/user-attachments/assets/546888de-4fba-4379-a844-844e73cade2b

WickM commented 1 month ago

Thank you very much. I was aple to get my skript working now. I was under the wrng impression that the binding had to be done together with the creation of an extended Task function.