django - Celery Task the difference between these two tasks below -
what's difference between these 2 tasks below?
the first 1 gives error, second 1 runs fine. both same, accept arguments , both called in same way.
processrequests.delay(batch) **error object.__new__() takes no parameters** sendmessage.delay(message.pk, self.pk) **works!!!!**
now, have been made aware of error means, confusion why 1 works , not other.
tasks...
1)
class processrequests(task): name = "request process" max_retries = 1 default_retry_delay = 3 def run(self, batch): #do
2)
class sendmessage(task): name = "sending sms" max_retries = 10 default_retry_delay = 3 def run(self, message_id, gateway_id=none, **kwargs): #do
full task code....
from celery.task import task celery.decorators import task import logging sms.models import message, gateway, batch contacts.models import contact accounts.models import transaction, account class sendmessage(task): name = "sending sms" max_retries = 10 default_retry_delay = 3 def run(self, message_id, gateway_id=none, **kwargs): logging.debug("about send message.") # because don't have control on transactions # in our calling code, retry 10 times, every 3 # seconds, in order try allow commit database # finish. gives server 30 seconds write of # data database, , finish view. try: message = message.objects.get(pk=message_id) except exception exc: raise sendmessage.retry(exc=exc) if not gateway_id: if hasattr(message.billee, 'sms_gateway'): gateway = message.billee.sms_gateway else: gateway = gateway.objects.all()[0] else: gateway = gateway.objects.get(pk=gateway_id) # check have credits sent me message account = account.objects.get(user=message.sender) # i'm getting non-cathed version here, check performance!!!!! if account._balance() >= message.length: response = gateway._send(message) if response.status == 'sent': # take credit users account. transaction = transaction( account=account, amount=- message.charge, description="debit: sms sent", ) transaction.save() message.billed = true message.save() else: pass logging.debug("done sending message.") class processrequests(task): name = "request process" max_retries = 1 default_retry_delay = 3 def run(self, message_batch): e in contact.objects.filter(contact_owner=message_batch.user, group=message_batch.group): msg = message.objects.create( recipient_number=e.mobile, content=message_batch.content, sender=e.contact_owner, billee=message_batch.user, sender_name=message_batch.sender_name ) gateway = gateway.objects.get(pk=2) msg.send(gateway) #replace('[firstname]', e.first_name)
tried:
processrequests.delay(batch) should work gives error error object.__new__() takes no parameters processrequests().delay(batch) gives error error object.__new__() takes no parameters
i able reproduce issue:
import celery celery.task import task @celery.task class foo(celery.task): name = "foo" def run(self, batch): print 'foo' class bar(celery.task): name = "bar" def run(self, batch): print 'bar' # subclass deprecated base task class class bar2(task): name = "bar2" def run(self, batch): print 'bar2' @celery.task(name='def-foo') def foo(batch): print 'foo'
output:
in [2]: foo.delay('x') [warning/poolworker-4] foo in [3]: foo().delay('x') [warning/poolworker-2] foo in [4]: bar().delay('x') [warning/poolworker-3] bar in [5]: foo.delay('x') typeerror: object.__new__() takes no parameters in [6]: bar.delay('x') typeerror: unbound method delay() must called bar instance first argument (got str instance instead) in [7]: bar2.delay('x') [warning/poolworker-1] bar2
i see use deprecated celery.task.task
base class, why don't unbound method
errors:
definition: task(self, *args, **kwargs) docstring: deprecated task base class. modern applications should use :class:`celery.task` instead.
i don't know why processrequests
doesn't work though. maybe caching issues, may have tried apply decorator class before , got cached, , error when try apply decorator task class.
delete .pyc file, restart celery workers , try again.
don't use classes directly
- tasks instantiated once per (worker) process, creating objects of task classes (on client-side) every time doesn't make sense, i.e.
bar()
wrong. foo.delay()
orfoo().delay()
might or might not work, depends on combination of decoratorname
argument , classname
attribute.
get task object celery.registry.tasks
dictionary or use @celery.task
decorator on functions (foo
in example) instead.