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 supplied to ‘.args’, with the objects passed as ‘...’ assigned to the global environment of that process.
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’.
For evaluation to occur as if in your global environment, supply objects to ‘...’ rather than ‘.args’, e.g. for free variables or helper functions defined in function bodies, as scoping rules may otherwise prevent them from being found.
Timeouts
Specifying the ‘.timeout’ argument ensures that the mirai always
resolves. However, the task may not have completed and still be ongoing in
the daemon process. Use stop_mirai
instead to explicitly stop
and interrupt a task.
Errors
If an error occurs in evaluation, the error message is returned as a
character string of class ‘miraiError’ and ‘errorValue’.
is_mirai_error
may be used to test for this. The elements of
the original condition are accessible via $
on the error object. A
stack trace comprising a list of calls is also available at
$stack.trace
.
If a daemon crashes or terminates unexpectedly during evaluation, an ‘errorValue’ 19 (Connection reset) is returned.
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)
m[]
# 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)
collect_mirai(m)
}