Task Timeout
In this page, I will introduce how to set the timeout or deadline for a task, and how to handle cancellation operations.
When queuing a task using Client
, you can specify Timeout
or Deadline
as an option. This allows the server to give up on the task and reclaim resources for other tasks if the task is not processed before the timeout or deadline.
These options will set the timeout or deadline of the context.Context
and pass it as the first parameter to your handler.
*Note: The timeout is relative to when the handler starts processing the task.
For example, if you have a task that needs to be completed within 30 seconds, you can set the timeout to 30*time.Second
.
c := asynq.NewClient(asynq.RedisClientOpt{Addr: ":6379"})
err := c.Enqueue(task, asynq.Timeout(30 * time.Second))
If you have a task that needs to be completed by a specific time, you can set the deadline for the task.
For example, if you have a task that needs to be completed before 2020-12-25
, you can pass it as a Deadline
option.
xmas := time.Date(2020, time.December, 25, 0, 0, 0, 0, time.UTC)
err := c.Enqueue(task, asynq.Deadline(xmas))
Task Context in Handlers
Now that we've created a task using the Timeout
and Deadline
options, we must respect this value by reading the Done
channel in the context.
The first parameter passed to Handler
is context.Context
. You should write your handler in a way that abandons work upon receiving a cancel signal from the context.
func myHandler(ctx context.Context, task *asynq.Task) error {
c := make(chan error, 1)
go func() {
c <- doWork(task)
}()
select {
case <-ctx.Done():
// Cancellation signal received, abandon this work.
return ctx.Err()
case res := <-c:
return res
}
}
Cancelling Tasks via CLI
The asynq
CLI has a cancel
command that can cancel the ID of an active task.
You can use the workers
command to check the currently active tasks and get the ID of the task to cancel.
asynq task ls --queue=myqueue --state=active
asynq task cancel [task_id]