简体   繁体   中英

Custom Celery Task class does not work properly

I am struggling to get Celery work. I am new to Python in general and obviously to Celery and I am trying to get basic example work. I would like to run a background task which should preserve it's state as long as it is alive. So I try to implement basic example of incrementing an integer variable when called from client script. I am working on Raspberry Pi with raspbian image. Here is my worker task code:

from celery import Task, registry, Celery
import celery

celery = Celery('tasks', broker='redis://localhost:6379',backend='redis://localhost:6379')

class MyTask(celery.Task):
        a = 0
        def __init__(self):
                self.a = 0

        def increment(self, x):
                self.a += x
                return self.a
        @property
        def a(self):
                return a

@celery.task(Base=MyTask)
def mytask(x):
        mytask.increment(x)
        return mytask.a

And this is the calling script:

from tasks import mytask

result = mytask.delay(2)
print result.get(timeout=1)

Which yields following error:

[2018-05-21 15:08:23,889: DEBUG/MainProcess] TaskPool: Apply <function _fast_trace_task at 0x7610cdf0> (args:('tasks.mytask', '3ae83225-faee-4dc0-a6c1-1a7e7e5eaca2', {'origin': 'gen27381@raspberrypi', 'lang': 'py', 'task': 'tasks.mytask', 'group': None, 'root_id': '3ae83225-faee-4dc0-a6c1-1a7e7e5eaca2', u'delivery_info': {u'priority': 0, u'redelivered': None, u'routing_key': 'celery', u'exchange': u''}, 'expires': None, u'correlation_id': '3ae83225-faee-4dc0-a6c1-1a7e7e5eaca2', 'retries': 0, 'timelimit': [None, None], 'argsrepr': '(2,)', 'eta': None, 'parent_id': None, u'reply_to': 'fdebe38f-7353-3ef2-920b-74f76a294ff7', 'id': '3ae83225-faee-4dc0-a6c1-1a7e7e5eaca2', 'kwargsrepr': '{}'}, '[[2], {}, {"chord": null, "callbacks": null, "errbacks": null, "chain": null}]', 'application/json', 'utf-8') kwargs:{})
[2018-05-21 15:08:23,894: DEBUG/MainProcess] Task accepted: tasks2.mytask[3ae83225-faee-4dc0-a6c1-1a7e7e5eaca2] pid:27366
Traceback (most recent call last):
  File "test2.py", line 4, in <module>
    print result.get(timeout=1)
  File "/usr/local/lib/python2.7/dist-packages/celery/result.py", line 194, in get
    on_message=on_message,
  File "/usr/local/lib/python2.7/dist-packages/celery/backends/async.py", line 191, in wait_for_pending
    return result.maybe_throw(callback=callback, propagate=propagate)
  File "/usr/local/lib/python2.7/dist-packages/celery/result.py", line 299, in maybe_throw
    self.throw(value, self._to_remote_traceback(tb))
  File "/usr/local/lib/python2.7/dist-packages/celery/result.py", line 292, in throw
    self.on_ready.throw(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/vine/promises.py", line 217, in throw
    reraise(type(exc), exc, tb)
  File "<string>", line 1, in reraise
celery.backends.base.AttributeError: 'mytask' object has no attribute 'increment'
[2018-05-21 15:08:23,910: ERROR/ForkPoolWorker-2] Task tasks.mytask[3ae83225-faee-4dc0-a6c1-1a7e7e5eaca2] raised unexpected: AttributeError("'mytask' object has no attribute 'increment'",)
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 374, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 629, in __protected_call__
    return self.run(*args, **kwargs)
  File "/home/pi/example/tasks.py", line 20, in mytask
    mytask.increment(x)
  File "/usr/local/lib/python2.7/dist-packages/celery/local.py", line 146, in __getattr__
    return getattr(self._get_current_object(), name)
AttributeError: 'mytask' object has no attribute 'increment'

The worker is added with command:

celery -A tasks worker --loglevel=debug

and the test script simply with

python test.py

I also tried to access the "a" variable directly and had same error as a result. It is obvious that I am doing something very basic wrongly, but I can not figure out what.

Ok so the problem was indeed very basic. Syntax for defining custom task class is not ChildClass(Base=ParentClass) but ChildClass(base=ParentClass)... I must have Copied it from some example and interpreter never thought to complain about any of it. There are several other problems also with the example in the question Here is code that actually does what it was supposed to do:

    from celery import Task, registry, Celery
    import celery


    class MyTask(celery.Task):
            a = 0

            def increment(self, x):
                    self.a += x
                    return self.a

    celery = Celery('tasks', broker='redis://localhost:6379',backend='redis://localhost:6379')
    @celery.task(base=MyTask)
    def fookyou(x):
            val = fookyou.increment(x)
            return val

Notice that I modified also the task name in case it was mixing with the custom class name when only difference was capital letters. It is apparently too much to ask from interpreter to spot that type of errors...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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