DavisVaughan / furrr

Apply Mapping Functions in Parallel using Futures
https://furrr.futureverse.org/
Other
699 stars 40 forks source link

Revisit `.env_globals` argument #153

Closed DavisVaughan closed 4 years ago

DavisVaughan commented 4 years ago

Somewhat related to https://github.com/HenrikBengtsson/future.apply/issues/62, since that also uses this env.

y actually shouldn't be found here.

What happens is that the function env of fn() is the global env. When future_map() searches for globals, it searches in the caller env, which contains y <- 1. So y is identified as a global and is exported to the worker and assigned into the global env on the worker, so it is found in the multisession plan

library(purrr)
library(furrr)

fn <- function(x) {
  y
}

wrapper <- function() {
  y <- 1
  fn(1)
}

wrapper2 <- function() {
  y <- 1
  map(1:5, fn)
}

wrapper3 <- function() {
  y <- 1
  future_map(1:5, fn)
}

wrapper()
#> Error in fn(1): object 'y' not found
wrapper2()
#> Error in .f(.x[[i]], ...): object 'y' not found

plan(sequential)
wrapper3()
#> Error in ...furrr_fn(...): object 'y' not found

plan(multisession, workers = 2)
wrapper3()
#> [[1]]
#> [1] 1
#> 
#> [[2]]
#> [1] 1
#> 
#> [[3]]
#> [1] 1
#> 
#> [[4]]
#> [1] 1
#> 
#> [[5]]
#> [1] 1

Created on 2020-08-10 by the reprex package (v0.3.0)

DavisVaughan commented 4 years ago

The more correct solution might be to look up .f globals in the fn_env(.f) and to lookup .x and ... globals in the caller env