J'essaie d'utiliser les méthodes de classe comme tâches Django-céleri, en les marquant à l'aide du décorateur @task. La même situation est décrite ici , demandée par Anand Jeyahar. C'est quelque chose comme ça
class A:
@task
def foo(self, bar):
...
def main():
a = A()
...
# what i need
a.foo.delay(bar) # executes as celery task
a.foo(bar) # executes locally
Le problème est même si j'utilise une instance de classe comme ceci a.foo.delay(bar)
il est dit que foo
a besoin d'au moins deux arguments, ce qui signifie que le pointeur self
manque.
Plus d'information:
run()
méthode, utilisant un argument comme clé pour la sélection de la méthode, mais ce n'est pas exactement ce que je veux.self
aux méthodes modifie la façon dont j'exécute les méthodes non pas comme des prises de céleri, mais comme méthodes habituelles (c.-à-d. pendant les tests)Merci de votre aide!
Celery a un support expérimental pour l'utilisation de méthodes comme tâches depuis la version 3.0.
La documentation à ce sujet se trouve dans celery.contrib.methods
, et mentionne également quelques mises en garde que vous devez connaître:
http://docs.celryproject.org/en/latest/reference/celery.contrib.methods.html
Attention : prise en charge de contrib.methods
supprimé de Céleri depuis 4.0
Jeremy Satterfield a un tutoriel propre et simple pour écrire des tâches basées sur la classe si c'est ce que vous voulez accomplir. Vous pouvez le vérifier ici .
La magie étend essentiellement la classe celery.Task
En incluant une méthode run()
, comme quelque chose comme ceci:
from celery import Task
class CustomTask(Task):
ignore_result = True
def __init__(self, arg):
self.arg = arg
def run(self):
do_something_with_arg(self.arg)
puis exécutez la tâche comme ceci:
your_arg = 3
custom_task = CustomTask()
custom_task.delay(your_arg)
Je ne sais pas si la partie ignore_result = True
Est nécessaire ou non BTW.
Lorsque vous avez:
a = A()
tu peux faire:
A.foo.delay(a, param0, .., paramN)
À votre santé
Pour moi, le seul qui fonctionne est celery.current_app car juste cela passe self
à la méthode.
Donc, cela devrait ressembler à ceci:
from celery import current_app
from celery.contrib.methods import task_method
class A:
@current_app.task(filter=task_method, name='A.foo')
def foo(self, bar):
...
Le nom doit être utilisé si vous avez une méthode avec le même nom dans différentes classes.