2

I have some of the analytics methods in models.py under class Analytics (e.g: Analytics.record_read_analytics()). And we are calling those methods for recording analytics, which doesn't need to be synchronous. Currently it's affecting rendering of each request so decided to add these methods in celery queue. We are already using celery for some of our tasks hence we have tasks.py and celery.py file.

Following is section of models.py file:

class Analytics():
    ...
    ...

    @staticmethod
    def method_a():
        ...
        ...


    def method_b():
        ...
        ...

    @staticmethod
    def record_read_analytics():
        ...
        ...

I don't wanted to write again same model level class methods in tasks.py and wanted to make some of view method's and model level class methods as celery task.

Following is celery.py file:

from __future__ import absolute_import
from celery import Celery

app = Celery('gnowsys_ndf',
             include=['gnowsys_ndf.tasks'])

app.config_from_object('gnowsys_ndf.celeryconfig')

if __name__ == '__main__':
    app.start()

I'm new to celery and looking for help. Thank you in advance.

Kedar.Aitawdekar
  • 2,364
  • 1
  • 23
  • 25
  • http://stackoverflow.com/questions/9250317/using-class-methods-as-celery-tasks – khajvah Sep 14 '16 at 12:14
  • Passing object arguments to celery function was giving an error but it was not visible to me so used [celery flower](http://flower.readthedocs.io/en/latest/) to dignose the problem and it pointed out correctly. Also thanks to @khajvah and Moinuddin for some useful corrections. Now it's working fine! – Kedar.Aitawdekar Sep 14 '16 at 15:24

2 Answers2

3

You can create tasks out of methods. The bad thing about this is that the object itself gets passed around (because the state of the object in worker has to be same as the state of the caller) in order for it to be called, so you lose some flexibility. So your object has to be pickled every time, which is why I am against this solution. Of course this concerns only class methods, static methods have no such problem.

Another solution, which I like, is to create separate tasks.py or class based tasks and call the methods from within them. This way, you will have FULL control over Analytics object within your worker.

khajvah
  • 4,889
  • 9
  • 41
  • 63
0

You may achieve it like:

analytics = Analytics()   # Object of Analytics class
Analytics.record_read_analytics.delay()

Also, you need to add @task decorator with the record_read_analytics function

Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126