Nested future-promises lose reactive context
Boglarka opened this issue · comments
System details
Output of sessionInfo()
:
R version 4.3.2 (2023-10-31)
Platform: x86_64-apple-darwin20 (64-bit)
Running under: macOS Monterey 12.7.4
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/lib/libRlapack.dylib; LAPACK version 3.11.0
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: Europe/Budapest
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] promises_1.3.0 future_1.33.2 shinyjs_2.1.0 shiny_1.8.1.1
loaded via a namespace (and not attached):
[1] crayon_1.5.2 cli_3.6.2 rlang_1.1.3 jsonlite_1.8.8 xtable_1.8-4 listenv_0.9.1
[7] htmltools_0.5.8.1 httpuv_1.6.15 sass_0.4.9 jquerylib_0.1.4 fastmap_1.1.1 lifecycle_1.0.4
[13] memoise_2.0.1 compiler_4.3.2 codetools_0.2-20 Rcpp_1.0.12 later_1.3.2 digest_0.6.35
[19] R6_2.5.1 parallelly_1.37.1 parallel_4.3.2 magrittr_2.0.3 bslib_0.7.0 tools_4.3.2
[25] withr_3.0.0 mime_0.12 globals_0.16.3 cachem_1.0.8
Example application or steps to reproduce the problem
library(shiny)
library(shinyjs)
library(future)
library(promises)
ui <- fluidPage(
shinyjs::useShinyjs(),
radioButtons(inputId = "sect",
label = "",
selected = "all",
choices = list("All" = "all",
"One" = "one",
"Two" = "two"
)
),
actionButton(inputId = "compute_rank", label = "Compute rank")
)
server <- function(input, output, session) {
observeEvent(input$compute_rank, {
handle_json(input$sect)
})
handle_json <- function(sect) {
future_promise ({
json_data <- retrieve_json_data(sect)
}) %...>% {
json_data <- .
# THIS WORKS
#shinyjs::hide("compute_rank")
#session$userData$result <- calculate_result()
future_promise ({
json_data2 <- retrieve_json_data(sect)
}) %...>% {
json_data2 <- .
# NOT WORKING
#shinyjs::hide("compute_rank")
#session$userData$result <- calculate_result()
future_promise ({
json_data3 <- retrieve_json_data(sect)
}) %...>% {
json_data3 <- .
# NOT WORKING
# shinyjs::hide("compute_rank")
# session$userData$result <- calculate_result()
}
}
}
}
retrieve_json_data <- function(data) {
return(paste0("selected: ", data))
}
get_result <- function(data) {
return(paste0("selected: ", data))
}
calculate_result <- reactive({get_result(data = input$sect)})
}
shinyApp(ui, server)
Describe the problem in detail
I upgraded to shiny 1.8.1.1 then my app started to throw different errors. After some hours of debugging, it turned out the problem is with this version of shiny package. When I downgraded to 1.8.0, everything works as before, as expected.
I created a small reprex based on my application. I use nested future_promises (because I have a progress bar and this way I can set it properly which I could not, using one future_promise only). It seems as if the reactive environment disappears in between the resolved promises or I'm not sure how to say it. There are multiple issues but all are related to losing reactivity. I included two issues which you can check.
First issue is related to shinyjs:
Warning: Error in : shinyjs: could not find the Shiny session object. This usually happens when a shinyjs function is called from a context that wasn't set up by a Shiny session.
You can check it using this line:
shinyjs::hide("compute_rank")
After the first future_promise is resolved, it works fine. After the second and third, it throws the error above.
Second issue is related to a reactive function:
Warning: Error in .getReactiveEnvironment()$currentContext: Operation not allowed without an active reactive context.
• You tried to do something that can only be done from inside a reactive consumer.
You can check it using this line:
session$userData$result <- calculate_result()
After the first future_promise is resolved, it works fine. After the second and third, it throws the error above.
Thanks in advance for your help.