Specify a non-blocking execution strategy for genproc()
Source:R/nonblocking_spec.R
nonblocking_spec.RdReturns a configuration object to pass as the nonblocking
argument of genproc(). When supplied, genproc() returns
immediately with a genproc_result of status "running" while
the actual work continues in a background future. Use status()
to poll the state and await() to block until completion.
Arguments
- strategy
Character, or
NULL. One of"sequential","multisession","multicore","cluster". Default"multisession". Unlikeparallel_spec(), the default is notNULL: a function named "non-blocking" must not silently block because the currentfuture::plan()is sequential. Passstrategy = NULLexplicitly to defer to the caller's plan."sequential"is accepted mainly for deterministic testing — it exercises the code path but does not actually free the console.- packages
Character vector, or
NULL. Extra packages to attach on the background worker before running. genproc itself is attached automatically for every strategy other than"sequential".- globals
Logical or character. Forwarded to
future::future()'sglobalsargument. DefaultTRUEenables automatic detection.
Composition with parallel_spec()
nonblocking_spec() and parallel_spec() are orthogonal and can
be combined. The non-blocking layer launches one outer future;
inside it, the parallel layer dispatches cases via
future.apply. With both strategies set to "multisession",
future resolves the inner layer as "sequential" by default
(see future::plan() nesting rules) unless the caller installs an
explicit nested plan via future::plan(list(...)).
On Windows and in some RStudio configurations, the wrapper
subprocess inherits getOption("mc.cores") set to 1, which would
lead parallelly to refuse the inner workers ("only 1 CPU core
available for this R process"), and to also emit a misleading
soft-limit warning even after the refusal is lifted. genproc()
works around both issues transparently in the composed case (only
when the user has not set their own values). See ?genproc for
details.
Examples
# Launch in the background, keep the console.
# \donttest{
spec <- nonblocking_spec()
job <- genproc(
f = function(x) x * 2,
mask = data.frame(x = 1:4),
nonblocking = spec
)
status(job) # "running"
#> [1] "running"
job <- await(job) # blocks until done
job$log
#> case_id x success error_message traceback duration_secs
#> 1 case_0001 1 TRUE <NA> <NA> 0
#> 2 case_0002 2 TRUE <NA> <NA> 0
#> 3 case_0003 3 TRUE <NA> <NA> 0
#> 4 case_0004 4 TRUE <NA> <NA> 0
# }
# Deterministic test: exercise the code path without real async
spec <- nonblocking_spec(strategy = "sequential")