Hi! I saw the new ExtendedTask() class and thought it would be perfect for my project. But I couldn't get it to work. Basically, I have a long running fetch I want to kick off (the "calc" in the example) while proceeding with separate preliminary data validation.
The below example actually works as intended on my computer, but operates differently when deployed (that is, blocking). Confusingly, when I tried putting this logic in my app, it also blocks locally (and deployed, I assume).
library(shiny)
library(bslib)
library(future)
library(promises)
future::plan(future::multisession)
# Define UI Module
taskUI <- function(id) {
ns <- NS(id)
page_sidebar(
sidebar = sidebar(
actionButton(ns("gen_data"), "Generate Data"),
actionButton(ns("check_data"),"Check File"),
uiOutput(ns("check_message")),
numericInput(ns("x"), "x", 5),
numericInput(ns("y"), "y", 6),
input_task_button(ns("calc"), "Calculate", type = "primary"),
p(
strong("Status: "),
textOutput(ns("status"), inline = TRUE)
)
),
tableOutput(ns("gen_data_results")),
h4("x * y (fast)"),
verbatimTextOutput(ns("result_fast")),
h4("x + y (extended/slow)"),
verbatimTextOutput(ns("result"), placeholder = TRUE)
)
}
# Define Server Module
taskServer <- function(id) {
moduleServer(id, function(input, output, session) {
adder_task <- ExtendedTask$new(function(x, y) {
# Simulation of a task
future_promise({
Sys.sleep(10) # Simulating a delay
x + y
})
}) |> bind_task_button(session$ns("calc"))
observeEvent(input$calc, {
adder_task$invoke(input$x, input$y)
})
output$status <- renderText({
adder_task$status()
})
output$result <- renderText({
adder_task$result()
})
output$result_fast <- renderText({
input$x * input$y
})
dataset <- eventReactive(input$gen_data, data.frame(row = 1:5, val = rnorm(5)))
output$gen_data_results <- renderTable(dataset())
observeEvent(input$check_data, {
if(nrow(dataset()) == 5){
output$check_message <- renderUI({
tags$div(
tags$br(),
paste("Works!", sample(1:5, 1), sum(dataset())),
tags$br()
)
})
}
})
})
}
# App UI
ui <- function(){
taskUI("calcModule") # Using the UI module
}
# App Server
server <- function(input, output, session) {
taskServer("calcModule") # Using the Server module
}
# Run the app
shinyApp(ui, server)