簡體   English   中英

Celery在使用Django數據庫執行之前撤銷任務

[英]Celery revoke task before execute using django database

由於並發原因,我使用的是Django數據庫而不是RabbitMQ。

但是我無法解決在執行任務之前將其撤消的問題。

我找到了有關此問題的一些答案,但它們似乎不完整,或者我無法獲得足夠的幫助。

當我不想執行任務時,如何使用模型擴展celery任務表,並添加一個布爾字段(撤消)以進行設置?

謝謝。

由於Celery通過ID跟蹤任務,因此您真正需要的就是能夠知道哪些ID已被取消。 您可以創建自己的表(或memcached等)來跟蹤已取消的ID,而不用修改kombu內部結構,然后檢查當前可取消任務的ID是否在其中。

這是支持遠程revoke命令的傳輸在內部執行的操作:

所有工作節點都在內存中或在磁盤上永久保留已撤銷的任務ID的內存(請參閱持久撤銷)。 (來自Celery文檔)

當您使用django傳輸時,您要自己負責。 在這種情況下,由每個任務來檢查是否已取消。

因此,任務的基本形式(添加日志代替實際操作)變為:

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")

您可以通過多種方式擴展和改進此功能,例如通過創建基本的CancelableTask類,就像您鏈接到的其他答案之一一樣,但這是基本形式。 您現在缺少的是模型和檢查它的功能。

請注意,這種情況下的ID將是字符串ID,例如a5644f08-7d30-43ff-a61e-81c165ad9e19而不是整數。 您的模型可以像這樣簡單:

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()

現在,您可以通過查看celery服務的調試日志來檢查行為,例如:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM