rstudio / promises

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

Restructure `future_promise()` example to have inline output in example #64

Closed schloerke closed 3 years ago

schloerke commented 3 years ago

From:

ftr_pr> if (require("future")) {
ftr_pr+   # Relative start time
ftr_pr+   start <- Sys.time()
ftr_pr+   # Helper to force two `future` workers
ftr_pr+   with_two_workers <- function(expr) {
ftr_pr+     old_plan <- future::plan(future::multisession(workers = 2))
ftr_pr+     on.exit({future::plan(old_plan)}, add = TRUE)
ftr_pr+     start <<- Sys.time()
ftr_pr+     force(expr)
ftr_pr+     while(!later::loop_empty()) {Sys.sleep(0.1); later::run_now()}
ftr_pr+     invisible()
ftr_pr+   }
ftr_pr+   # Print a status message. Ex: `"PID: XXX; 2.5s promise done"`
ftr_pr+   print_msg <- function(pid, msg) {
ftr_pr+     message(
ftr_pr+       "PID: ", pid, "; ",
ftr_pr+       round(difftime(Sys.time(), start, units = "secs"), digits = 1), "s " ,
ftr_pr+       msg
ftr_pr+     )
ftr_pr+   }
ftr_pr+
ftr_pr+   # `"promise done"` will appear after four workers are done and the main R session is not blocked
ftr_pr+   # The important thing to note is the first four times will be roughly the same
ftr_pr+   with_two_workers({
ftr_pr+     promise_resolve(Sys.getpid()) %...>% print_msg("promise done")
ftr_pr+     for (i in 1:6) future::future({Sys.sleep(1); Sys.getpid()}) %...>% print_msg("future done")
ftr_pr+   })
ftr_pr+   #> PID: XXX; 2.5s promise done
ftr_pr+   #> PID: YYY; 2.6s future done
ftr_pr+   #> PID: ZZZ; 2.6s future done
ftr_pr+   #> PID: YYY; 2.6s future done
ftr_pr+   #> PID: ZZZ; 2.6s future done
ftr_pr+   #> PID: YYY; 3.4s future done
ftr_pr+   #> PID: ZZZ; 3.6s future done
ftr_pr+
ftr_pr+   # `"promise done"` will almost immediately, before any workers have completed
ftr_pr+   # The first two `"future done"` comments appear earlier the example above
ftr_pr+   with_two_workers({
ftr_pr+     promise_resolve(Sys.getpid()) %...>% print_msg("promise")
ftr_pr+     for (i in 1:6) future_promise({Sys.sleep(1); Sys.getpid()}) %...>% print_msg("future done")
ftr_pr+   })
ftr_pr+   #> PID: XXX; 0.2s promise done
ftr_pr+   #> PID: YYY; 1.3s future done
ftr_pr+   #> PID: ZZZ; 1.4s future done
ftr_pr+   #> PID: YYY; 2.5s future done
ftr_pr+   #> PID: ZZZ; 2.6s future done
ftr_pr+   #> PID: YYY; 3.4s future done
ftr_pr+   #> PID: ZZZ; 3.6s future done
ftr_pr+ }
Loading required package: future
PID: 31177; 2.6s promise done
PID: 31395; 2.7s future done
PID: 31421; 2.7s future done
PID: 31395; 2.7s future done
PID: 31421; 2.7s future done
PID: 31395; 3.4s future done
PID: 31421; 3.6s future done
PID: 31177; 0.2s promise
PID: 31449; 1.3s future done
PID: 31475; 1.4s future done
PID: 31449; 2.4s future done
PID: 31475; 2.6s future done
PID: 31449; 3.6s future done
PID: 31475; 3.7s future done

To:

> example(future_promise)

ftr_pr>## No test:
ftr_pr># Relative start time
ftr_pr> start <- Sys.time()
ftr_pr> # Helper to force two `future` workers
ftr_pr> with_two_workers <- function(expr) {
ftr_pr+   if (!require("future")) {
ftr_pr+     message("`future` not installed")
ftr_pr+     return()
ftr_pr+   }
ftr_pr+   old_plan <- future::plan(future::multisession(workers = 2))
ftr_pr+   on.exit({future::plan(old_plan)}, add = TRUE)
ftr_pr+   start <<- Sys.time()
ftr_pr+   force(expr)
ftr_pr+   while(!later::loop_empty()) {Sys.sleep(0.1); later::run_now()}
ftr_pr+   invisible()
ftr_pr+ }
ftr_pr> # Print a status message. Ex: `"PID: XXX; 2.5s promise done"`
ftr_pr> print_msg <- function(pid, msg) {
ftr_pr+   message(
ftr_pr+     "PID: ", pid, "; ",
ftr_pr+     round(difftime(Sys.time(), start, units = "secs"), digits = 1), "s " ,
ftr_pr+     msg
ftr_pr+   )
ftr_pr+ }
ftr_pr> # `"promise done"` will appear after four workers are done and the main R session is not blocked
ftr_pr> # The important thing to note is the first four times will be roughly the same
ftr_pr> with_two_workers({
ftr_pr+   promise_resolve(Sys.getpid()) %...>% print_msg("promise done")
ftr_pr+   for (i in 1:6) future::future({Sys.sleep(1); Sys.getpid()}) %...>% print_msg("future done")
ftr_pr+ })
Loading required package: future
PID: 42842; 2.5s promise done
PID: 43062; 2.6s future done
PID: 43088; 2.6s future done
PID: 43062; 2.6s future done
PID: 43088; 2.6s future done
PID: 43062; 3.4s future done
PID: 43088; 3.6s future done
ftr_pr> {
ftr_pr+ #> PID: XXX; 2.5s promise done
ftr_pr+ #> PID: YYY; 2.6s future done
ftr_pr+ #> PID: ZZZ; 2.6s future done
ftr_pr+ #> PID: YYY; 2.6s future done
ftr_pr+ #> PID: ZZZ; 2.6s future done
ftr_pr+ #> PID: YYY; 3.4s future done
ftr_pr+ #> PID: ZZZ; 3.6s future done
ftr_pr+ }
NULL
ftr_pr> # `"promise done"` will almost immediately, before any workers have completed
ftr_pr> # The first two `"future done"` comments appear earlier the example above
ftr_pr> with_two_workers({
ftr_pr+   promise_resolve(Sys.getpid()) %...>% print_msg("promise")
ftr_pr+   for (i in 1:6) future_promise({Sys.sleep(1); Sys.getpid()}) %...>% print_msg("future done")
ftr_pr+ })
PID: 42842; 0.2s promise
PID: 43116; 1.3s future done
PID: 43142; 1.4s future done
PID: 43116; 2.5s future done
PID: 43142; 2.6s future done
PID: 43116; 3.6s future done
PID: 43142; 3.7s future done
ftr_pr> {
ftr_pr+ #> PID: XXX; 0.2s promise done
ftr_pr+ #> PID: YYY; 1.3s future done
ftr_pr+ #> PID: ZZZ; 1.4s future done
ftr_pr+ #> PID: YYY; 2.5s future done
ftr_pr+ #> PID: ZZZ; 2.6s future done
ftr_pr+ #> PID: YYY; 3.4s future done
ftr_pr+ #> PID: ZZZ; 3.6s future done
ftr_pr+ }
NULL
ftr_pr> ## End(No test)