rstudio / promises

A promise library for R
https://rstudio.github.io/promises
Other
197 stars 19 forks source link

`promise_map` failed to run in parallel #84

Closed lz100 closed 1 year ago

lz100 commented 1 year ago

Following the tutorial on this page, promise_map should work in parallel, but it is not.

library(promises)
library(future)
plan(multisession, workers = 8)

aaa <- promise_map(1:3, function(x) {
    future_promise({
        Sys.sleep(5)
        Sys.time()
    })
}) 
aaa %...>% print 

#[[1]]
#[1] "2022-07-29 16:20:37 PDT"

#[[2]]
#[1] "2022-07-29 16:20:42 PDT"

#[[3]]
#[1] "2022-07-29 16:20:47 PDT"

It is sequential.

If function from future is used, then it works.

bbb <- future.apply::future_lapply(1:3, function(x) {
        Sys.sleep(5)
        Sys.time()
})
bbb
#[[1]]
#[1] "2022-07-29 16:20:37 PDT"

#[[2]]
#[1] "2022-07-29 16:20:37 PDT"

#[[3]]
#[1] "2022-07-29 16:20:37 PDT"
─ Session info ───────────────────────────────
 setting  value
 version  R version 4.1.2 (2021-11-01)
 os       Rocky Linux 8.5 (Green Obsidian)
 system   x86_64, linux-gnu
 ui       RStudio
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       America/Los_Angeles
 date     2022-07-29
 rstudio  2022.02.0+443 Prairie Trillium (server)
 pandoc   2.17.1.1 @ /bigdata/operations/pkgadmin/opt/linux/centos/8.x/x86_64/pkgs/rstudio-server/2022.02.0-443/bin/quarto/bin/ (via markdown)

promises 1.2.0.1
future 1.23.0
jcheng5 commented 1 year ago

This is actually working as intended, but the way that you can achieve what you want is also documented. On the page you linked, search for “promise_map works serially” and read from there to the end of that section.

lz100 commented 1 year ago

Thanks for the info. I missed this part. But it's confusing to achieve such a goal, why would users call an outside function and use strange syntax like .list = . to do such?

jcheng5 commented 1 year ago

You don't need to use an outside function, you just need a list of promises, and purrr::map is one concise way to gather up the results of function calls into a list. You could do the same thing with an lapply or for-loop if you want. As for .list = ., that's pretty idiomatic modern R code but you can do it in a more literal fashion if you want.

Here's a more "base R" way to do it:

promises <- lapply(packages, get_pub_date)
pkg_dates <- promise_all(.list = promises)