Robin  van Leeuwen
Robin van Leeuwen

Reputation: 2703

Celery: update state of task when using classes

Hi i'm trying to update the state of a method which is executed as a task:

As described in : http://docs.celeryproject.org/en/latest/reference/celery.contrib.methods.html

from celery import Celery

celery = Celery()

class A(object):

    def __init__(self):
        self.a = 0

    @celery.task(filter=task_method)
    def add(self):
         self.a += 10

         for i in range(10):
             self.update_state(state="PROGRESS", meta={
                 "current": i, "total": 10, "status": "Sleeping"
             })


         return {"current": 100, "total": 100, "status": "Complete."}



a = A()
a.add.delay()

Which gives an error:

AttributeError: 'A' object has no attribute 'update_state'

Which seems logical to me since A does not inherit from task, so it hasn't got the "update_task" method.

Question: How do i update the state of an task when using method based tasks ???

Update: As described in the comments below, updating the status of a task which is not bound is impossible, therefore the celery.contrib.methods way of defining methods as tasks is not usable in my example.

Upvotes: 0

Views: 5756

Answers (1)

MarSoft
MarSoft

Reputation: 3913

Probably you can do it like that:

from celery import Celery, current_task

celery = Celery()

class A:
  @celery.task(filter=task_method)
  def add(self):
    # ...
    current_task.update_state('PROGRESS', meta={...})

a = A()
a.add.delay()

Notice that I use current_task proxy instead of the self variable (which, in contrary to class methods, denotes current task in bound Celery tasks).

Alternatively (didn't check that but probably it should work as well), you may be able to bind class method task as well:

class A:
  @celery.task(filter=task_method, bind=True)
  def add(self, task):
    task.update_state('PROGRESS', meta={...})

Probably you'll have to exchange self and task arguments for them to work properly, not sure about that.

BTW, it seems that celery.contrib.methods was removed in Celery 4.0.

Upvotes: 1

Related Questions