R6
class for controller groups.
See also
Other controller_group:
crew_controller_group()
Active bindings
controllers
List of
R6
controller objects.relay
Relay object for event-driven programming on a downstream condition variable.
Methods
Method new()
Multi-controller constructor.
Usage
crew_class_controller_group$new(controllers = NULL, relay = NULL)
Arguments
controllers
List of
R6
controller objects.relay
Relay object for event-driven programming on a downstream condition variable.
Examples
if (identical(Sys.getenv("CREW_EXAMPLES"), "true")) {
persistent <- crew_controller_local(name = "persistent")
transient <- crew_controller_local(
name = "transient",
tasks_max = 1L
)
group <- crew_controller_group(persistent, transient)
group$start()
group$push(name = "task", command = sqrt(4), controller = "transient")
group$wait()
group$pop()
group$terminate()
}
Method empty()
See if the controllers are empty.
Method nonempty()
Check if the controller group is nonempty.
Method resolved()
Number of resolved mirai()
tasks.
Method saturated()
Check if a controller is saturated.
Arguments
collect
Deprecated in version 0.5.0.9003 (2023-10-02). Not used.
throttle
Deprecated in version 0.5.0.9003 (2023-10-02). Not used.
controller
Character vector of length 1 with the controller name. Set to
NULL
to select the default controller thatpush()
would choose.
Details
A controller is saturated if the number of unresolved tasks
is greater than or equal to the maximum number of workers.
In other words, in a saturated controller, every available worker
has a task.
You can still push tasks to a saturated controller, but
tools that use crew
such as targets
may choose not to.
Method start()
Start one or more controllers.
Method launch()
Launch one or more workers on one or more controllers.
Method scale()
Automatically scale up the number of workers if needed in one or more controller objects.
Arguments
throttle
TRUE
to skip auto-scaling if it already happened within the lastseconds_interval
seconds.FALSE
to auto-scale every timescale()
is called. Throttling avoids overburdening themirai
dispatcher and other resources.controllers
Character vector of controller names. Set to
NULL
to select all controllers.
Details
See the scale()
method in individual controller classes.
Method autoscale()
Run worker auto-scaling in a private later
loop
every controller$client$seconds_interval
seconds.
Method descale()
Terminate the auto-scaling loop started by
controller$autoscale()
.
Method push()
Push a task to the head of the task list.
Arguments
command
Language object with R code to run.
data
Named list of local data objects in the evaluation environment.
globals
Named list of objects to temporarily assign to the global environment for the task. See the
reset_globals
argument ofcrew_controller_local()
.substitute
Logical of length 1, whether to call
base::substitute()
on the supplied value of thecommand
argument. IfTRUE
(default) thencommand
is quoted literally as you write it, e.g.push(command = your_function_call())
. IfFALSE
, thencrew
assumescommand
is a language object and you are passing its value, e.g.push(command = quote(your_function_call()))
.substitute = TRUE
is appropriate for interactive use, whereassubstitute = FALSE
is meant for automated R programs that invokecrew
controllers.seed
Integer of length 1 with the pseudo-random number generator seed to set for the evaluation of the task. Passed to the
seed
argument ofset.seed()
if notNULL
. Ifalgorithm
andseed
are bothNULL
, then the random number generator defaults to the widely spaced worker-specific L'Ecuyer streams as supported bymirai::nextstream()
. Seevignette("parallel", package = "parallel")
for details.algorithm
Integer of length 1 with the pseudo-random number generator algorithm to set for the evaluation of the task. Passed to the
kind
argument ofRNGkind()
if notNULL
. Ifalgorithm
andseed
are bothNULL
, then the random number generator defaults to the recommended widely spaced worker-specific L'Ecuyer streams as supported bymirai::nextstream()
. Seevignette("parallel", package = "parallel")
for details.packages
Character vector of packages to load for the task.
library
Library path to load the packages. See the
lib.loc
argument ofrequire()
.seconds_timeout
Optional task timeout passed to the
.timeout
argument ofmirai::mirai()
(after converting to milliseconds).scale
Logical, whether to automatically scale workers to meet demand. See the
scale
argument of thepush()
method of ordinary single controllers.throttle
TRUE
to skip auto-scaling if it already happened within the lastseconds_interval
seconds.FALSE
to auto-scale every timescale()
is called. Throttling avoids overburdening themirai
dispatcher and other resources.name
Optional name of the task. Replaced with a random name if
NULL
or in conflict with an existing name in the task list.save_command
Logical of length 1. If
TRUE
, the controller deparses the command and returns it with the output onpop()
. IfFALSE
(default), the controller skips this step to increase speed.controller
Character of length 1, name of the controller to submit the task. If
NULL
, the controller defaults to the first controller in the list.
Returns
Invisibly return the mirai
object of the pushed task.
This allows you to interact with the task directly, e.g.
to create a promise object with promises::as.promise()
.
Method walk()
Apply a single command to multiple inputs, and return control to the user without waiting for any task to complete.
Arguments
command
Language object with R code to run.
iterate
Named list of vectors or lists to iterate over. For example, to run function calls
f(x = 1, y = "a")
andf(x = 2, y = "b")
, setcommand
tof(x, y)
, and setiterate
tolist(x = c(1, 2), y = c("a", "b"))
. The individual function calls are evaluated asf(x = iterate$x[[1]], y = iterate$y[[1]])
andf(x = iterate$x[[2]], y = iterate$y[[2]])
. All the elements ofiterate
must have the same length. If there are any name conflicts betweeniterate
anddata
,iterate
takes precedence.data
Named list of constant local data objects in the evaluation environment. Objects in this list are treated as single values and are held constant for each iteration of the map.
globals
Named list of constant objects to temporarily assign to the global environment for each task. This list should include any functions you previously defined in the global environment which are required to run tasks. See the
reset_globals
argument ofcrew_controller_local()
. Objects in this list are treated as single values and are held constant for each iteration of the map.substitute
Logical of length 1, whether to call
base::substitute()
on the supplied value of thecommand
argument. IfTRUE
(default) thencommand
is quoted literally as you write it, e.g.push(command = your_function_call())
. IfFALSE
, thencrew
assumescommand
is a language object and you are passing its value, e.g.push(command = quote(your_function_call()))
.substitute = TRUE
is appropriate for interactive use, whereassubstitute = FALSE
is meant for automated R programs that invokecrew
controllers.seed
Integer of length 1 with the pseudo-random number generator seed to set for the evaluation of the task. Passed to the
seed
argument ofset.seed()
if notNULL
. Ifalgorithm
andseed
are bothNULL
, then the random number generator defaults to the recommended widely spaced worker-specific L'Ecuyer streams as supported bymirai::nextstream()
. Seevignette("parallel", package = "parallel")
for details.algorithm
Integer of length 1 with the pseudo-random number generator algorithm to set for the evaluation of the task. Passed to the
kind
argument ofRNGkind()
if notNULL
. Ifalgorithm
andseed
are bothNULL
, then the random number generator defaults to the recommended widely spaced worker-specific L'Ecuyer streams as supported bymirai::nextstream()
. Seevignette("parallel", package = "parallel")
for details.packages
Character vector of packages to load for the task.
library
Library path to load the packages. See the
lib.loc
argument ofrequire()
.seconds_timeout
Optional task timeout passed to the
.timeout
argument ofmirai::mirai()
(after converting to milliseconds).names
Optional character of length 1, name of the element of
iterate
with names for the tasks. Ifnames
is supplied, theniterate[[names]]
must be a character vector.save_command
Logical of length 1, whether to store a text string version of the R command in the output.
scale
Logical, whether to automatically scale workers to meet demand. See also the
throttle
argument.throttle
TRUE
to skip auto-scaling if it already happened within the lastseconds_interval
seconds.FALSE
to auto-scale every timescale()
is called. Throttling avoids overburdening themirai
dispatcher and other resources.controller
Character of length 1, name of the controller to submit the tasks. If
NULL
, the controller defaults to the first controller in the list.
Method map()
Apply a single command to multiple inputs.
Usage
crew_class_controller_group$map(
command,
iterate,
data = list(),
globals = list(),
substitute = TRUE,
seed = NULL,
algorithm = NULL,
packages = character(0),
library = NULL,
seconds_interval = 0.5,
seconds_timeout = NULL,
names = NULL,
save_command = FALSE,
error = "stop",
warnings = TRUE,
verbose = interactive(),
scale = TRUE,
throttle = TRUE,
controller = NULL
)
Arguments
command
Language object with R code to run.
iterate
Named list of vectors or lists to iterate over. For example, to run function calls
f(x = 1, y = "a")
andf(x = 2, y = "b")
, setcommand
tof(x, y)
, and setiterate
tolist(x = c(1, 2), y = c("a", "b"))
. The individual function calls are evaluated asf(x = iterate$x[[1]], y = iterate$y[[1]])
andf(x = iterate$x[[2]], y = iterate$y[[2]])
. All the elements ofiterate
must have the same length. If there are any name conflicts betweeniterate
anddata
,iterate
takes precedence.data
Named list of constant local data objects in the evaluation environment. Objects in this list are treated as single values and are held constant for each iteration of the map.
globals
Named list of constant objects to temporarily assign to the global environment for each task. This list should include any functions you previously defined in the global environment which are required to run tasks. See the
reset_globals
argument ofcrew_controller_local()
. Objects in this list are treated as single values and are held constant for each iteration of the map.substitute
Logical of length 1, whether to call
base::substitute()
on the supplied value of thecommand
argument. IfTRUE
(default) thencommand
is quoted literally as you write it, e.g.push(command = your_function_call())
. IfFALSE
, thencrew
assumescommand
is a language object and you are passing its value, e.g.push(command = quote(your_function_call()))
.substitute = TRUE
is appropriate for interactive use, whereassubstitute = FALSE
is meant for automated R programs that invokecrew
controllers.seed
Integer of length 1 with the pseudo-random number generator seed to set for the evaluation of the task. Passed to the
seed
argument ofset.seed()
if notNULL
. Ifalgorithm
andseed
are bothNULL
, then the random number generator defaults to the recommended widely spaced worker-specific L'Ecuyer streams as supported bymirai::nextstream()
. Seevignette("parallel", package = "parallel")
for details.algorithm
Integer of length 1 with the pseudo-random number generator algorithm to set for the evaluation of the task. Passed to the
kind
argument ofRNGkind()
if notNULL
. Ifalgorithm
andseed
are bothNULL
, then the random number generator defaults to the recommended widely spaced worker-specific L'Ecuyer streams as supported bymirai::nextstream()
. Seevignette("parallel", package = "parallel")
for details.packages
Character vector of packages to load for the task.
library
Library path to load the packages. See the
lib.loc
argument ofrequire()
.seconds_interval
Number of seconds to wait between auto-scaling operations while waiting for tasks to complete.
seconds_timeout
Optional task timeout passed to the
.timeout
argument ofmirai::mirai()
(after converting to milliseconds).names
Optional character of length 1, name of the element of
iterate
with names for the tasks. Ifnames
is supplied, theniterate[[names]]
must be a character vector.save_command
Logical of length 1, whether to store a text string version of the R command in the output.
error
Character vector of length 1, choice of action if a task has an error. Possible values:
"stop"
: throw an error in the main R session instead of returning a value. In case of an error, the results from the last erroredmap()
are in theerror
field of the controller, e.g.controller_object$error
. To reduce memory consumption, setcontroller_object$error <- NULL
after you are finished troubleshooting."warn"
: throw a warning. This allows the return value with all the error messages and tracebacks to be generated."silent"
: do nothing special.
warnings
Logical of length 1, whether to throw a warning in the interactive session if at least one task encounters an error.
verbose
Logical of length 1, whether to print progress messages.
scale
Logical, whether to automatically scale workers to meet demand. See also the
throttle
argument.throttle
TRUE
to skip auto-scaling if it already happened within the lastseconds_interval
seconds.FALSE
to auto-scale every timescale()
is called. Throttling avoids overburdening themirai
dispatcher and other resources.controller
Character of length 1, name of the controller to submit the tasks. If
NULL
, the controller defaults to the first controller in the list.
Method pop()
Pop a completed task from the results data frame.
Usage
crew_class_controller_group$pop(
scale = TRUE,
collect = NULL,
throttle = TRUE,
error = NULL,
controllers = NULL
)
Arguments
scale
Logical, whether to automatically scale workers to meet demand. See the
scale
argument of thepop()
method of ordinary single controllers.collect
Deprecated in version 0.5.0.9003 (2023-10-02). Not used.
throttle
TRUE
to skip auto-scaling if it already happened within the lastseconds_interval
seconds.FALSE
to auto-scale every timescale()
is called. Throttling avoids overburdening themirai
dispatcher and other resources.error
NULL
or character of length 1, choice of action if the popped task threw an error. Possible values:"stop"
: throw an error in the main R session instead of returning a value."warn"
: throw a warning.NULL
or"silent"
: do not react to errors.
controllers
Character vector of controller names. Set to
NULL
to select all controllers.
Method collect()
Pop all available task results and return them in a tidy
tibble
.
Usage
crew_class_controller_group$collect(
scale = TRUE,
throttle = TRUE,
error = NULL,
controllers = NULL
)
Arguments
scale
Logical of length 1, whether to automatically call
scale()
to auto-scale workers to meet the demand of the task load.throttle
TRUE
to skip auto-scaling if it already happened within the lastseconds_interval
seconds.FALSE
to auto-scale every timescale()
is called. Throttling avoids overburdening themirai
dispatcher and other resources.error
NULL
or character of length 1, choice of action if the popped task threw an error. Possible values:"stop"
: throw an error in the main R session instead of returning a value."warn"
: throw a warning.NULL
or"silent"
: do not react to errors.
controllers
Character vector of controller names. Set to
NULL
to select all controllers.
Method promise()
Create a promises::promise()
object to asynchronously
pop or collect one or more tasks.
Usage
crew_class_controller_group$promise(
mode = "one",
seconds_interval = 0.1,
scale = NULL,
throttle = NULL,
controllers = NULL
)
Arguments
mode
Character of length 1, what kind of promise to create.
mode
must be"one"
or"all"
. Details:If
mode
is"one"
, then the promise is fulfilled (or rejected) when at least one task is resolved and available topop()
. When that happens,pop()
runs asynchronously, pops a result off the task list, and returns a value. If the task succeeded, then the promise is fulfilled and its value is the result ofpop()
(a one-rowtibble
with the result and metadata). If the task threw an error, the error message of the task is forwarded to any error callbacks registered with the promise.If
mode
is"all"
, then the promise is fulfilled (or rejected) when there are no unresolved tasks left in the controller. (Be careful: this condition is trivially met in the moment if the controller is empty and you have not submitted any tasks, so it is best to create this kind of promise only after you submit tasks.) When there are no unresolved tasks left,collect()
runs asynchronously, pops all available results off the task list, and returns a value. If the task succeeded, then the promise is fulfilled and its value is the result ofcollect()
(atibble
with one row per task result). If any of the tasks threw an error, then the first error message detected is forwarded to any error callbacks registered with the promise.
seconds_interval
Positive numeric of length 1, delay in the
later::later()
polling interval to asynchronously check if the promise can be resolved.scale
Deprecated on 2024-04-10 (version 0.9.1.9003) and no longer used. Now,
promise()
always turns on auto-scaling in a privatelater
loop (if not already activated).throttle
Deprecated on 2024-04-10 (version 0.9.1.9003) and no longer used. Now,
promise()
always turns on auto-scaling in a privatelater
loop (if not already activated).controllers
Not used. Included to ensure the signature is compatible with the analogous method of controller groups.
Details
Please be aware that pop()
or collect()
will happen
asynchronously at a some unpredictable time after the promise object
is created, even if your local R process appears to be doing
something completely different. This behavior is highly desirable
in a Shiny reactive context, but please be careful as it may be
surprising in other situations.
Returns
A promises::promise()
object whose eventual value will
be a tibble
with results from one or more popped tasks.
If mode = "one"
, only one task is popped and returned (one row).
If mode = "all"
, then all the tasks are returned in a tibble
with one row per task (or NULL
is returned if there are no
tasks to pop).
Method wait()
Wait for tasks.
Usage
crew_class_controller_group$wait(
mode = "all",
seconds_interval = 0.5,
seconds_timeout = Inf,
scale = TRUE,
throttle = TRUE,
controllers = NULL
)
Arguments
mode
Character of length 1:
"all"
to wait for all tasks in all controllers to complete,"one"
to wait for a single task in a single controller to complete. In this scheme, the timeout limit is applied to each controller sequentially, and a timeout is treated the same as a completed controller.seconds_interval
Number of seconds to interrupt the wait in order to scale up workers as needed.
seconds_timeout
Timeout length in seconds waiting for results to become available.
scale
Logical of length 1, whether to call
scale_later()
on each selected controller to schedule auto-scaling. See thescale
argument of thewait()
method of ordinary single controllers.throttle
TRUE
to skip auto-scaling if it already happened within the lastseconds_interval
seconds.FALSE
to auto-scale every timescale()
is called. Throttling avoids overburdening themirai
dispatcher and other resources.controllers
Character vector of controller names. Set to
NULL
to select all controllers.
Method push_backlog()
Push the name of a task to the backlog.
Method pop_backlog()
Pop the task names from the head of the backlog which can be pushed without saturating the controller.
Method summary()
Summarize the workers of one or more controllers.
Returns
A data frame of aggregated worker summary statistics
of all the selected controllers. It has one row per worker,
and the rows are grouped by controller.
See the documentation of the summary()
method of the controller
class for specific information about the columns in the output.
Examples
if (identical(Sys.getenv("CREW_EXAMPLES"), "true")) {
persistent <- crew_controller_local(name = "persistent")
transient <- crew_controller_local(
name = "transient",
tasks_max = 1L
)
group <- crew_controller_group(persistent, transient)
group$start()
group$push(name = "task", command = sqrt(4), controller = "transient")
group$wait()
group$pop()
group$terminate()
}
## ------------------------------------------------
## Method `crew_class_controller_group$new`
## ------------------------------------------------
if (identical(Sys.getenv("CREW_EXAMPLES"), "true")) {
persistent <- crew_controller_local(name = "persistent")
transient <- crew_controller_local(
name = "transient",
tasks_max = 1L
)
group <- crew_controller_group(persistent, transient)
group$start()
group$push(name = "task", command = sqrt(4), controller = "transient")
group$wait()
group$pop()
group$terminate()
}