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]