View source: R/future_promise.R
future_promise_queue | R Documentation |
future_promise_queue()
future_promise(
expr = NULL,
envir = parent.frame(),
substitute = TRUE,
globals = TRUE,
packages = NULL,
...,
queue = future_promise_queue()
)
expr |
An R expression. While the |
envir |
The environment from where global objects should be identified. |
substitute |
If TRUE, argument |
globals |
(optional) a logical, a character vector, or a named list
to control how globals are handled.
For details, see section 'Globals used by future expressions'
in the help for |
packages |
(optional) a character vector specifying packages to be attached in the R environment evaluating the future. |
... |
extra parameters provided to |
queue |
A queue that is used to schedule work to be done using |
When submitting future work, future (by design) will block the main R session until a worker becomes available.
This occurs when there is more submitted future work than there are available future workers.
To counter this situation, we can create a promise to execute work using future (using future_promise()
) and only begin the work if a future worker is available.
Using future_promise()
is recommended whenever a continuous runtime is used, such as with plumber or shiny.
For more details and examples, please see the vignette("future_promise", "promises")
vignette.
Unlike future::future()
, future_promise()
returns a promise()
object that will eventually resolve the future expr
.
future_promise_queue()
: Default future_promise()
work queue to use. This function returns a WorkQueue that is cached per R session.
future_promise()
: Creates a promise()
that will execute the expr
using future::future()
.
WorkQueue
# Relative start time
start <- Sys.time()
# Helper to force two `future` workers
with_two_workers <- function(expr) {
if (!require("future")) {
message("`future` not installed")
return()
}
old_plan <- future::plan(future::multisession(workers = 2))
on.exit({future::plan(old_plan)}, add = TRUE)
start <<- Sys.time()
force(expr)
while(!later::loop_empty()) {Sys.sleep(0.1); later::run_now()}
invisible()
}
# Print a status message. Ex: `"PID: XXX; 2.5s promise done"`
print_msg <- function(pid, msg) {
message(
"PID: ", pid, "; ",
round(difftime(Sys.time(), start, units = "secs"), digits = 1), "s " ,
msg
)
}
# `"promise done"` will appear after four workers are done and the main R session is not blocked
# The important thing to note is the first four times will be roughly the same
with_two_workers({
promise_resolve(Sys.getpid()) %...>% print_msg("promise done")
for (i in 1:6) future::future({Sys.sleep(1); Sys.getpid()}) %...>% print_msg("future done")
})
{
#> PID: XXX; 2.5s promise done
#> PID: YYY; 2.6s future done
#> PID: ZZZ; 2.6s future done
#> PID: YYY; 2.6s future done
#> PID: ZZZ; 2.6s future done
#> PID: YYY; 3.4s future done
#> PID: ZZZ; 3.6s future done
}
# `"promise done"` will almost immediately, before any workers have completed
# The first two `"future done"` comments appear earlier the example above
with_two_workers({
promise_resolve(Sys.getpid()) %...>% print_msg("promise")
for (i in 1:6) future_promise({Sys.sleep(1); Sys.getpid()}) %...>% print_msg("future done")
})
{
#> PID: XXX; 0.2s promise done
#> PID: YYY; 1.3s future done
#> PID: ZZZ; 1.4s future done
#> PID: YYY; 2.5s future done
#> PID: ZZZ; 2.6s future done
#> PID: YYY; 3.4s future done
#> PID: ZZZ; 3.6s future done
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.