Skip to contents

Returns 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.

Usage

nonblocking_spec(strategy = "multisession", packages = NULL, globals = TRUE)

Arguments

strategy

Character, or NULL. One of "sequential", "multisession", "multicore", "cluster". Default "multisession". Unlike parallel_spec(), the default is not NULL: a function named "non-blocking" must not silently block because the current future::plan() is sequential. Pass strategy = NULL explicitly 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()'s globals argument. Default TRUE enables automatic detection.

Value

A list of class "genproc_nonblocking_spec" with the validated, normalized fields.

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")