简体   繁体   English

Celery在使用Django数据库执行之前撤销任务

[英]Celery revoke task before execute using django database

I'm using Django database instead of RabbitMQ for concurrency reasons. 由于并发原因,我使用的是Django数据库而不是RabbitMQ。

But I can't solve the problem of revoking a task before it execute. 但是我无法解决在执行任务之前将其撤消的问题。

I found some answers about this matter but they don't seem complete or I can't get enough help. 我找到了有关此问题的一些答案,但它们似乎不完整,或者我无法获得足够的帮助。

How can I extend celery task table using a model, add a boolean field (revoked) to set when I don't want the task to execute? 当我不想执行任务时,如何使用模型扩展celery任务表,并添加一个布尔字段(撤消)以进行设置?

Thanks. 谢谢。

Since Celery tracks tasks by an ID, all you really need is to be able to tell which IDs have been canceled. 由于Celery通过ID跟踪任务,因此您真正需要的就是能够知道哪些ID已被取消。 Rather than modifying kombu internals, you can create your own table (or memcached etc) that just tracks canceled IDs, then check whether the ID for the current cancelable task is in it. 您可以创建自己的表(或memcached等)来跟踪已取消的ID,而不用修改kombu内部结构,然后检查当前可取消任务的ID是否在其中。

This is what the transports that support a remote revoke command do internally: 这是支持远程revoke命令的传输在内部执行的操作:

All worker nodes keeps a memory of revoked task ids, either in-memory or persistent on disk (see Persistent revokes). 所有工作节点都在内存中或在磁盘上永久保留已撤销的任务ID的内存(请参阅持久撤销)。 (from Celery docs) (来自Celery文档)

When you use the django transport, you are responsible for doing this yourself. 当您使用django传输时,您要自己负责。 In this case it's up to each task to check whether it has been canceled. 在这种情况下,由每个任务来检查是否已取消。

So the basic form of your task (logging added in place of an actual operation) becomes: 因此,任务的基本形式(添加日志代替实际操作)变为:

from celery import shared_task
from celery.exceptions import Ignore
from celery.utils.log import get_task_logger
from .models import task_canceled
logger = get_task_logger(__name__)

@shared_task
def my_task():
    if task_canceled(my_task.request.id):
        raise Ignore
    logger.info("Doing my stuff")

You can extend & improve this in various ways, such as by creating a base CancelableTask class as in one of the other answers you linked to, but this is the basic form. 您可以通过多种方式扩展和改进此功能,例如通过创建基本的CancelableTask类,就像您链接到的其他答案之一一样,但这是基本形式。 What you're missing now is the model and the function to check it. 您现在缺少的是模型和检查它的功能。

Note that the ID in this case will be a string ID like a5644f08-7d30-43ff-a61e-81c165ad9e19 , not an integer. 请注意,这种情况下的ID将是字符串ID,例如a5644f08-7d30-43ff-a61e-81c165ad9e19而不是整数。 Your model can be as simple as this: 您的模型可以像这样简单:

from django.db import models

class CanceledTask(models.Model):
    task_id = models.CharField(max_length=200)

def cancel_task(request_id):
    CanceledTask.objects.create(task_id=request_id)

def task_canceled(request_id):
    return CanceledTask.objects.filter(task_id=request_id).exists()

You can now check the behavior by watching your celery service's debug logs while doing things like: 现在,您可以通过查看celery服务的调试日志来检查行为,例如:

my_task.delay()
models.cancel_task(my_task.delay())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM