一架梯子,一头程序猿,仰望星空!
Asynq任务队列教程 > 内容正文

任务超时&撤销


在本页面中,我将介绍如何设置任务的超时时间或截止时间,以及如何处理取消操作。

任务超时

当使用 Client 排队一个任务时,你可以指定 TimeoutDeadline 作为一个选项。这样,如果任务在超时时间或截止时间之前未被处理,服务器可以放弃该任务以重新获取其他任务的资源。
这些选项将设置 context.Context 的超时时间或截止时间,将其作为第一个参数传递给你的处理程序。

*注意: 超时时间是相对于处理程序开始处理任务的时间

例如,如果你有一个需要在30秒内完成的任务,你可以将超时时间设置为 30*time.Second

c := asynq.NewClient(asynq.RedisClientOpt{Addr: ":6379"})

err := c.Enqueue(task, asynq.Timeout(30 * time.Second))

如果你有一个需要在特定时间之前完成的任务,你可以设置该任务的截止时间。
例如,如果你有一个需要在 2020-12-25 之前完成的任务,你可以将其作为 Deadline 选项传递。

xmas := time.Date(2020, time.December, 12, 25, 0, 0, 0, time.UTC)
err := c.Enqueue(task, asynq.Deadline(xmas))

处理程序中的任务上下文

现在,我们使用了 TimeoutDeadline 选项创建了任务,我们必须通过读取上下文中的 Done 通道来尊重该值。

传递给 Handler 的第一个参数是 context.Context。你应该以这样的方式编写你的处理程序,即在从上下文接收到取消信号时放弃工作。

func myHandler(ctx context.Context, task *asynq.Task) error {
    c := make(chan error, 1)
    go func() {
        c <- doWork(task)
    }()
    select {
    case <-ctx.Done():
        // cancelation signal received, abandon this work.
        return ctx.Err()
    case res := <-c:
        return res
    }   
}

通过cli取消任务

asynq CLI 有一个 cancel 命令,可以取消活动任务的ID。
你可以使用 workers 命令检查当前活动任务,并获取要取消的任务的ID。

asynq task ls --queue=myqueue --state=active
asynq task cancel [task_id]