簡體   English   中英

包含具有屬性的 celery 任務的裝飾器

[英]Decorator that includes celery task with attributes

我正在開發一個包含多個應用程序的 Django 項目,每個應用程序都有自己的任務集,並且運行良好。 但是,一般來說,每個應用程序的任務集使用相同的屬性來進行速率限制、重試等。我試圖創建一個具有所有這些通用屬性的裝飾器,並將目標 function 設置為任務。

所以,我的example/tasks.py中有這個:

from celery import current_app


@current_app.task(
    queue='example_queue',
    max_retries=3,
    rate_limit='10/s')
def example_task_1():
    ...

@current_app.task(
    queue='example_queue',
    max_retries=3,
    rate_limit='10/s')
def example_task_2():
    ...

我正在嘗試類似的東西:

from celery import current_app, Task


class ExampleTask(Task):

    def __init__(self, task, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.task = task

    def run(self):
        self.task()


def example_decorator_task(func):

    @wraps(func)
    def wrapped(self, *args, **kwargs):
        return ExampleTask(func).delay(
            queue='example_queue',
            max_retries=3,
            rate_limit='10/s')

@example_decorator_task
def example_task_1():
    ...

@example_decorator_task
def example_task_2():
    ...

我得到了這個工作,但是通過調用example_task_1.delay(...)任務不會像往常一樣工作,因為正在包裝內執行。 有任何想法嗎?

使用apply_async而不是delay ,您的裝飾器應該更改為:

def decorator(function):
    def wrapper(*args, **kwargs):
        return function.apply_async(args=[*args], kwargs={**kwargs}, **{
            'queue': 'example_queue',
            'max_retries': 3,
            'rate_limit': '10/s'
        })
    return wrapper

更多細節:

當您傳遞參數時,參數化裝飾器會轉換為無參數裝飾器,但不會將它們應用於 function。 因此,您可以通過將結果存儲到變量中來創建新的裝飾器,然后您可以將其應用於各種任務函數。 看:

from celery import current_app

rate_limited_task = current_app.task(
    queue='example_queue',
    max_retries=3,
    rate_limit='10/s'
)

@rate_limited_task
def example_task_1():
    ...

@rate_limited_task
def example_task_2():
    ...

暫無
暫無

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

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