Evaluate an expression asynchronously in a new background R process or persistent daemon (local or remote). This function will return immediately with a ‘mirai’, which will resolve to the evaluated result once complete.
Usage
mirai(.expr, ..., .args = list(), .timeout = NULL, .compute = "default")
Arguments
- .expr
an expression to evaluate asynchronously (of arbitrary length, wrapped in { } where necessary), or else a pre-constructed language object.
- ...
(optional) either named arguments (name = value pairs) specifying objects referenced, but not defined, in ‘.expr’, or an environment containing such objects. See ‘evaluation’ section below.
- .args
(optional) either a named list specifying objects referenced, but not defined, in ‘.expr’, or an environment containing such objects. These objects will remain local to the evaluation environment as opposed to those supplied in ‘...’ above - see ‘evaluation’ section below.
- .timeout
[default NULL] for no timeout, or an integer value in milliseconds. A mirai will resolve to an ‘errorValue’ 5 (timed out) if evaluation exceeds this limit.
- .compute
[default 'default'] character value for the compute profile to use (each compute profile has its own independent set of daemons).
Details
This function will return a ‘mirai’ object immediately.
The value of a mirai may be accessed at any time at $data
, and if yet
to resolve, an ‘unresolved’ logical NA will be returned instead.
unresolved
may be used on a mirai, returning TRUE if a
‘mirai’ has yet to resolve and FALSE otherwise. This is suitable for
use in control flow statements such as while
or if
.
Alternatively, to call (and wait for) the result, use
call_mirai
on the returned ‘mirai’. This will block
until the result is returned.
Specify ‘.compute’ to send the mirai using a specific compute profile
(if previously created by daemons
), otherwise leave as
‘default’.
Evaluation
The expression ‘.expr’ will be evaluated in a separate R process in a clean environment (not the global environment), consisting only of the objects in the list or environment supplied to ‘.args’, with the named objects passed as ‘...’ (from the environment if one was supplied) assigned to the global environment of that process.
For evaluation to occur as if in your global environment, supply objects to ‘...’ rather than ‘.args’. For stricter scoping, use ‘.args’, which limits, for example, where variables not explicitly passed as arguments to functions are found.
As evaluation occurs in a clean environment, all undefined objects must be
supplied though ‘...’ and/or ‘.args’, including self-defined
functions. Functions from a package should use namespaced calls such as
mirai::mirai()
, or else the package should be loaded beforehand as
part of ‘.expr’.
Errors
If an error occurs in evaluation, the error message is returned as a
character string of class ‘miraiError’ and ‘errorValue’ (the
stack trace is available at $stack.trace
on the error object).
is_mirai_error
may be used to test for this.
If a daemon crashes or terminates unexpectedly during evaluation, an
‘errorValue’ 19 (Connection reset) is returned (when not using
dispatcher or using dispatcher with retry = FALSE
). Otherwise, using
dispatcher with retry = TRUE
, the mirai will remain unresolved and is
automatically re-tried on the next daemon to connect to the particular
instance. To cancel the task instead, use saisei(force = TRUE)
(see
saisei
).
is_error_value
tests for all error conditions including
‘mirai’ errors, interrupts, and timeouts.
Examples
if (interactive()) {
# Only run examples in interactive R sessions
# specifying objects via '...'
n <- 3
m <- mirai(x + y + 2, x = 2, y = n)
m
m$data
Sys.sleep(0.2)
m$data
# passing the calling environment to '...'
df1 <- data.frame(a = 1, b = 2)
df2 <- data.frame(a = 3, b = 1)
m <- mirai(as.matrix(rbind(df1, df2)), environment(), .timeout = 1000)
call_mirai(m)$data
# using unresolved()
m <- mirai(
{
res <- rnorm(n)
res / rev(res)
},
n = 1e6
)
while (unresolved(m)) {
cat("unresolved\n")
Sys.sleep(0.1)
}
str(m$data)
# evaluating scripts using source() in '.expr'
n <- 10L
file <- tempfile()
cat("r <- rnorm(n)", file = file)
m <- mirai({source(file); r}, file = file, n = n)
call_mirai(m)[["data"]]
unlink(file)
# use source(local = TRUE) when passing in local variables via '.args'
n <- 10L
file <- tempfile()
cat("r <- rnorm(n)", file = file)
m <- mirai({source(file, local = TRUE); r}, .args = list(file = file, n = n))
call_mirai(m)[["data"]]
unlink(file)
# passing a language object to '.expr' and a named list to '.args'
expr <- quote(a + b + 2)
args <- list(a = 2, b = 3)
m <- mirai(.expr = expr, .args = args)
call_mirai(m)$data
}