You can save compute resources by stopping the execution of job
s that are no
longer needed. If that job
is currently running, then the associated
background process is terminated. Terminated background process are
automatically replaced by new ones.
There are several ways to stop a Job:
<job>$stop()
: return an interrupt condition.<job>$output<-
: return a custom result.<job>$stop_id
: replace redundant job
s.<job>$copy_id
: combine redundant job
s.<job>$timeout
: cap a job
's compute time.library(jobqueue) jq <- jobqueue(workers = 1)
As soon as a job
is created, it can be stopped by either calling
<job>$stop()
or by assigning to <job>$output
. These methods work up until
the job
state is 'done'
. Once the job
state is 'done'
, <job>$output
is
immutable and calling <job>$stop()
will have no effect (since it's already
stopped). Calling <job>$stop()
and assigning to <job>$output
both have the
side effect of setting the job
state to 'done'
.
<job>$stop()
job <- job_class$new({ Sys.sleep(5); 10 }) job$stop() job$result #> <interrupt: job stopped by user> job <- job_class$new({ Sys.sleep(5); 10 }) job$stop('my reason') job$result #> <interrupt: my reason> class(job$result) #> [1] "interrupt" "condition"
You can call <job>$stop()
from within callback hooks.
hooks <- list( 'created' = function (job) { if (length(job$vars$x) > 100) job$stop('Job is too large.') } ) job <- jq$run({ sum(x) }, vars = list(x = 1:200), hooks = hooks) job$result #> <interrupt: Job is too large.>
<job>$output
<job>$output
can only be assigned to once. If the job
is not yet done when
<job>$output
is assigned, then any ongoing processing will be halted.
job <- job_class$new({ Sys.sleep(5); 10 }) job$state #> [1] "created" job$output <- "Custom result" job$state #> [1] "done" job$result #> [1] "Custom result"
If you've set <job>$reformat
, it will determine <job>$result
as usual.
See vignette('results')
.
Sometimes repeat job
s may be sent to the jobqueue
, for instance, a user
clicking a 'submit' button repeatedly. stop_id
and copy_id
can prevent such
requests from overloading the server.
New jobs will replace existing job
s with the same stop_id
.
job1 <- jq$run({ Sys.sleep(5); 'A' }, stop_id = 123) job2 <- jq$run({ 'B' }, stop_id = 123) job1$result #> <interrupt: duplicated stop_id> job2$result #> [1] "B"
New job
s will mirror the output of existing job
s with the same copy_id
.
job1 <- jq$run({ Sys.sleep(5); 'A' }, copy_id = 456) job2 <- jq$run({ 'B' }, copy_id = 456) job1$result #> [1] "A" job2$result #> [1] "A"
jobqueue()
If you set stop_id
and/or copy_id
in jobqueue()
, then they must be
functions (or lambda notation functions) that accept a job
object as input and
returns a value id
. If id
is NULL
, then no comparisons will be done.
Otherwise, id
can be any data type and will be compared to other id
s with
identical()
.
jq <- jobqueue(stop_id = function (job) list(job$vars$f, job$user_id)) job1 <- jq$run({ f(x) }, vars = list(f = sum, x = 1:10), user_id = 'A') job2 <- jq$run({ f(x) }, vars = list(f = sum, x = 1:2), user_id = 'A') job3 <- jq$run({ f(x) }, vars = list(f = mean, x = 1:10), user_id = 'A') job1$result #> <interrupt: duplicated stop_id> job2$result #> [1] 3 job3$result #> [1] 5.5
job <- job_class$new({ Sys.sleep(5); 'Zzzzz' }, timeout = 0.2) jq$submit(job) job$result #> <interrupt: total runtime exceeded 0.2 seconds> job <- job_class$new({ 10 }, timeout = list(created = 0.2)) job$result #> <interrupt: exceeded 0.2 seconds while in "created" state>
Limits (in seconds) can be set on:
'submitted'
to 'done'
time: timeout = 2
timeout = list(queued = 1, running = 2)
timeout = list(total = 3, queued = 2, running = 2)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.