mirai offers the following functions primarily for package authors using mirai:
require_daemons() will error and prompt the user to set
daemons (with a clickable function link if the cli package is available)
if daemons are not already set.daemons_set(), to detect if daemons have already been
set.on_daemon(), to detect if code is already running on a
daemon, i.e. within a mirai() call.register_serial() to register custom serialization
functions, which are automatically available by default for all
subsequent daemons() calls.nextget(), for querying values for a compute profile,
such as ‘url’, described in the function’s documentation. Note: only the
specifically-documented values are supported interfaces.mirai as a framework is designed to support completely transparent and inter-operable use within packages. A core design precept of not relying on global options or environment variables minimises the likelihood of conflict between use by different packages.
There are hence only a few important points to note:
daemons() settings should wherever possible be left to
end-users. This means that as a package author, you should just consider
that mirai are run on whatever resources are available to the user at
the time the code is run. You do not need to anticipate whether an
end-user will run the code on their own machine, distributed over the
network, or a mixture of both.mirai::daemons(), or re-exporting daemons() in
your package as a convenience.daemons() when using
mirai_map(). This is important to ensure that there is no
accidental recursive creation of daemons on the same machine, for
example if your function is used within another package’s function that
also uses mirai.
The exception to this rule is that package authors may decide to provide a fallback to synchronous behaviour to ensure that a map always runs even if the user has not set daemons. In this case, it is permissible to set synchronous daemons for the duration of the map, if daemons have not been set, and provided that they are reset after the map. For this purpose, you may use code such as:
with(if (!daemons_set()) daemons(sync = TRUE), {
mirai_map(...)
})daemons(n = 1, dispatcher = FALSE, .compute = ...) call may
be used to set up a single dedicated daemon, but only if used with a
unique value for .compute. A representative example of this
usage pattern is logger::appender_async(), where the logger
package’s ‘namespace’ concept maps directly to mirai’s ‘compute
profile’.status() call must not be
used programmatically, as this user interface is subject to change at
any time. Use info() instead.status()$daemons, instead use
nextget("url").info() may be used programmatically, but only index
into the vector using the name of the element rather than its position
e.g. info()[["cumulative"]] rather than
info()[[2]]. This is in case other values are added at a
later date.
The functions unresolved(),
is_error_value(), is_mirai_error(), and
is_mirai_interrupt() should be used to test for the
relevant state of a mirai or its value.
dispatcher = FALSE) to ensure
that only one additional process is used, to remain within the 2-core
limit.daemons(0) at the end of each
example or test file. Then allow at least a one-second sleep to ensure
that all background processes have properly exited and that no
‘detritus’ from the processes remains.asyncdial or
autoexit for daemon(), in that function or any
functions that pass arguments through to it such as
daemons(). This is to ensure that processes exit as soon as
the host process does.