futureverse / futureverse/future
Entire global environment getting passed along with user-defined (global) functions in shiny
- Dominant language
- R
- Stars
- 1k
- Forks
- 92
- PR merge metrics
- No merged PRs in 30d
Description
**Describe the bug**
When calling a global function in a future (_promise) the entire global environment is getting passed along with the user-defined function. This, in a shiny context, also includes the server and the ui function, which depending on the apps size results in a long processing time.
This might be a [regression](https://github.com/futureverse/future/issues/176) (or promises::future_promise()'s behaviour?).
**Reproduce example**
```
library(future)
library(shiny)
library(bslib)
library(promises)
library(future.mirai)
plan(future.mirai::mirai_multisession)
some_other_global_var <- 1L
# size: 21750
# global_function <- local(function(){
# # Slow operation
# Sys.sleep(2)
# sample(1:100, 1)
# })
# size: 418991
global_function <- function(){
# Slow operation
Sys.sleep(2)
sample(1:100, 1)
}
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() {
print(environment(global_function))
print(ls(environment(global_function)))
print(future:::objectSize(global_function))
future_promise(
{
global_function()
}, seed = 1L
)
})
bind_task_button(rand_task, "recalculate")
observeEvent(input$recalculate, {
# Invoke the extended in an observer
rand_task$invoke()
})
output$result <- renderText({
number <- rand_task$result()
paste0("Your number is ", number, ".")
})
}
shinyApp(ui, server)
```
**Expected behavior**
Passing only the needed objects.
**Session information**
```r
R version 4.6.0 (2026-04-24 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 10 x64 (build 19045)
Matrix products: default
LAPACK version 3.12.1
locale:
[1] LC_COLLATE=German_Germany.utf8 LC_CTYPE=German_Germany.utf8 LC_MONETARY=German_Germany.utf8 LC_NUMERIC=C
[5] LC_TIME=German_Germany.utf8
time zone: Europe/Berlin
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] future.mirai_1.0.0 promises_1.5.0 bslib_0.11.0 future_1.70.0 shiny_1.14.0
loaded via a namespace (and not attached):
[1] jsonlite_2.0.0 compiler_4.6.0 Rcpp_1.1.1-1.1 parallel_4.6.0 later_1.4.8 jquerylib_0.1.4 globals_0.19.1 fastmap_1.2.0
[9] mime_0.13 R6_2.6.1 nanonext_1.9.1 tibble_3.3.1 mirai_2.7.1 pillar_1.11.1 rlang_1.2.0 cachem_1.1.0
[17] httpuv_1.6.17 fs_2.1.0 sass_0.4.10 otel_0.2.0 memoise_2.0.1 cli_3.6.6 withr_3.0.3 magrittr_2.0.5
[25] digest_0.6.39 rstudioapi_0.19.0 fontawesome_0.5.3 xtable_1.8-8 lifecycle_1.0.5 vctrs_0.7.3 glue_1.8.1 listenv_1.0.0
[33] codetools_0.2-20 parallelly_1.47.0 pkgconfig_2.0.3 tools_4.6.0 htmltools_0.5.9
…
*** Package versions
future 1.70.0, parallelly 1.47.0, parallel 4.6.0, globals 0.19.1, listenv 1.0.0
*** Allocations
availableCores():
system /proc/self/status
4 4
availableWorkers():
$system
[1] "localhost" "localhost" "localhost" "localhost"
*** Settings
- future.plan=
- future.fork.multithreading.enable=
- future.globals.maxSize=
- future.globals.onReference=
- future.resolve.recursive=
- future.rng.onMisuse=
- future.wait.timeout=
- future.wait.interval=
- future.wait.alpha=
- future.startup.script=
*** Backends
Number of workers: 4
List of future strategies:
1. mirai_multisession:
- args: function (..., workers = availableCores(), envir = parent.frame())
- tweaked: FALSE
- call: plan(future.mirai::mirai_multisession)
*** Basic tests
Main R session details:
pid r sysname release version nodename machine login user effective_user
1 8372 4.6.0 Windows 10 x64 build 19045 host001 x86-64 user001 user001 user001
…
```
Contributor guide
Research direction
Start by running the reproducible Shiny example with future.mirai::mirai_multisession and inspect the reported environment and object size for global_function. Compare the behavior of future_promise() with the referenced future issue and determine why the server and UI are included. Done means only the needed objects are passed and the unnecessary processing time is removed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- r
- Domain
- distributed-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100