library(jobqueue)
jq <- jobqueue()
my_job <- jq$run({ 42 })
# === A 'jobqueue'-style callback ============
my_job$on('done', ~message('Result = ', .$result))
#> Result = 42
# === A 'promises'-style callback ============
my_job %...>% message('Result = ', .)
#> Result = 42See also vignette('hooks')
When expr is finished evaluating, the result is assigned
to <job>$output.
By default, <job>$result will return the exact
same value as <job>$output.
However, while <job>$output is a fixed value,
<job>$result is highly configurable. Most notably by
the reformat and signal parameters.
Use reformat = function (job) {...} to define what
should be returned by <job>$result.
Important
You may access
job$outputin yourreformatfunction.
DO NOT accessjob$result, which would start an infinite recusion.
reformat can be set in several places:
jobqueue(reformat = http_wrap)<jobqueue>$run(reformat = http_wrap)<job>$reformat <- http_wrapjob Details<job>$output blocks until the job is
done. If you want <job>$result to not block, you can
return a placeholder value instead.
By default, errors and interrupts will be caught by the
jobqueue and returned as a condition object from
<job>$result.
expr <- quote(stop('error XYZ'))
job <- jq$run(expr)
x <- job$result
inherits(x, 'condition')
#> TRUE
x
#> <simpleError in eval(expr, envir, enclos): error XYZ>If you want those errors to continue propagating, set
signal = TRUE.
job <- jq$run(expr, signal = TRUE)
x <- job$result
#> Error:
#> ! stop("error XYZ")
#> Caused by error:
#> ! error XYZ
#> Run `rlang::last_trace()` to see where the error occurred.These signals can be caught as usual by try() and
tryCatch().
print_cnd <- function (cnd) cli::cli_text('Caught {.type {cnd}}.')
job <- jq$run({ Sys.sleep(5) }, signal = TRUE)$stop()
res <- tryCatch(job$result, error = print_cnd, interrupt = print_cnd)
#> Caught an <interrupt> object.
res
#> NULL
job <- jq$run({ stop('error XYZ') }, signal = TRUE)
res <- tryCatch(job$result, error = print_cnd, interrupt = print_cnd)
#> Caught an <error> object.
res
#> NULLYou can also signal some conditions while catching others. Perhaps stopping a job is part of the “normal” workflow and shouldn’t be lumped in with other errors.
You can pass a job directly to any function that expects
a promise object, such as promises::then or
promises::%...>%. These functions are re-exported by
jobqueue, so calling library(promises) is
optional.
By default, errors and interrupts are caught by jobqueue
and used for promise fulfillment.
onFulfilled <- function (value) cli::cli_text('Fulfilled with {.type {value}}.')
onRejected <- function (err) cli::cli_text('Rejected with {.type {err}}.')
job <- jq$run({ Sys.sleep(5) })$stop()
job %>% then(onFulfilled, onRejected)
#> Fulfilled with an <interrupt> object.
job <- jq$run({ stop('error XYZ') })
job %>% then(onFulfilled, onRejected)
#> Fulfilled with an <error> object.Setting signal = TRUE will cause errors and interrupts
be sent to the promise’s rejection handler instead.