From d37beeece77d61d2df5ebfd13696b26eac7c3b2f Mon Sep 17 00:00:00 2001 From: Dean Attali Date: Fri, 6 Dec 2024 14:24:01 -0500 Subject: [PATCH] ExtendedTask: add example to docs (#4087) Co-authored-by: Garrick Aden-Buie --- NEWS.md | 2 ++ R/extended-task.R | 48 +++++++++++++++++++++++++++++++++++++++++++ man/ExtendedTask.Rd | 50 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/NEWS.md b/NEWS.md index 359deea445..6394c4dcd4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,8 @@ * Improve collection of deep stack traces (stack traces that are tracked across steps in an async promise chain) with `coro` async generators such as `elmer` chat streams. Previously, Shiny treated each iteration of an async generator as a distinct deep stack, leading to pathologically long stack traces; now, Shiny only keeps/prints unique deep stack trace, discarding duplicates. (#4156) +* Added an example to the `ExtendedTask` documentation. (@daattali #4087) + ## Bug fixes * Fixed a bug in `conditionalPanel()` that would cause the panel to repeatedly show/hide itself when the provided condition was not boolean. (@kamilzyla, #4127) diff --git a/R/extended-task.R b/R/extended-task.R index 659a41f471..e29e78dafe 100644 --- a/R/extended-task.R +++ b/R/extended-task.R @@ -41,6 +41,54 @@ #' is, a function that quickly returns a promise) and allows even that very #' session to immediately unblock and carry on with other user interactions. #' +#' @examplesIf rlang::is_interactive() && rlang::is_installed("future") +#' +#' library(shiny) +#' library(bslib) +#' library(future) +#' plan(multisession) +#' +#' ui <- page_fluid( +#' titlePanel("Extended Task Demo"), +#' p( +#' 'Click the button below to perform a "calculation"', +#' "that takes a while to perform." +#' ), +#' input_task_button("recalculate", "Recalculate"), +#' p(textOutput("result")) +#' ) +#' +#' server <- function(input, output) { +#' rand_task <- ExtendedTask$new(function() { +#' future( +#' { +#' # Slow operation goes here +#' Sys.sleep(2) +#' sample(1:100, 1) +#' }, +#' seed = TRUE +#' ) +#' }) +#' +#' # Make button state reflect task. +#' # If using R >=4.1, you can do this instead: +#' # rand_task <- ExtendedTask$new(...) |> bind_task_button("recalculate") +#' bind_task_button(rand_task, "recalculate") +#' +#' observeEvent(input$recalculate, { +#' # Invoke the extended in an observer +#' rand_task$invoke() +#' }) +#' +#' output$result <- renderText({ +#' # React to updated results when the task completes +#' number <- rand_task$result() +#' paste0("Your number is ", number, ".") +#' }) +#' } +#' +#' shinyApp(ui, server) +#' #' @export ExtendedTask <- R6Class("ExtendedTask", portable = TRUE, cloneable = FALSE, public = list( diff --git a/man/ExtendedTask.Rd b/man/ExtendedTask.Rd index 893017320b..ade5334bd8 100644 --- a/man/ExtendedTask.Rd +++ b/man/ExtendedTask.Rd @@ -45,6 +45,56 @@ is, a function that quickly returns a promise) and allows even that very session to immediately unblock and carry on with other user interactions. } +\examples{ +\dontshow{if (rlang::is_interactive() && rlang::is_installed("future")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} + +library(shiny) +library(bslib) +library(future) +plan(multisession) + +ui <- page_fluid( + titlePanel("Extended Task Demo"), + p( + 'Click the button below to perform a "calculation"', + "that takes a while to perform." + ), + input_task_button("recalculate", "Recalculate"), + p(textOutput("result")) +) + +server <- function(input, output) { + rand_task <- ExtendedTask$new(function() { + future( + { + # Slow operation goes here + Sys.sleep(2) + sample(1:100, 1) + }, + seed = TRUE + ) + }) + + # Make button state reflect task. + # If using R >=4.1, you can do this instead: + # rand_task <- ExtendedTask$new(...) |> bind_task_button("recalculate") + bind_task_button(rand_task, "recalculate") + + observeEvent(input$recalculate, { + # Invoke the extended in an observer + rand_task$invoke() + }) + + output$result <- renderText({ + # React to updated results when the task completes + number <- rand_task$result() + paste0("Your number is ", number, ".") + }) +} + +shinyApp(ui, server) +\dontshow{\}) # examplesIf} +} \section{Methods}{ \subsection{Public methods}{ \itemize{