I have two tasks, where I need to call two different API to send a SMS and an email.
def ...:
...
send_payment_failed_sms.delay(payment_log.id, 1)
task_send_booking_failed_email(payment_log.id, 1)
But I always get the folowing error on the task to send SMS, but the task sending email works fine:
[2018-07-12 20:47:03,519: INFO/MainProcess] Received task: payments.tasks.send_payment_failed_sms[ac4f1c2a-f09d-4e79-89c9-dfe1ab26b25d]
[2018-07-12 20:47:18,548: WARNING/MainProcess] Soft time limit (15s) exceeded for payments.tasks.send_payment_failed_sms[ac4f1c2a-f09d-4e79-89c9-dfe1ab26b25d]
[2018-07-12 20:47:18,563: WARNING/ForkPoolWorker-1] on_failure
[2018-07-12 20:47:18,563: WARNING/ForkPoolWorker-1] ac4f1c2a-f09d-4e79-89c9-dfe1ab26b25d
[2018-07-12 20:47:18,564: WARNING/ForkPoolWorker-1] 'ac4f1c2a-f09d-4e79-89c9-dfe1ab26b25d' failed: SoftTimeLimitExceeded()
[2018-07-12 20:47:18,564: ERROR/ForkPoolWorker-1] Task payments.tasks.send_payment_failed_sms[ac4f1c2a-f09d-4e79-89c9-dfe1ab26b25d] raised unexpected: SoftTimeLimitExceeded()
Traceback (most recent call last):
...
billiard.exceptions.SoftTimeLimitExceeded: SoftTimeLimitExceeded()
@shared_task(bind=True, base=MyBaseClassForTask, max_retries=5, default_retry_delay=1 * 60, soft_time_limit=15,
time_limit=30)
def send_payment_failed_sms(self, payment_id, reason):
try:
try:
payload = ""
headers = {'content-type': 'application/x-www-form-urlencoded'}
url = 'https://sms-site.com/apikey=' + api_key + '&to=%s&var1=%s' % (
mobile, payment_log.id
)
response = requests.request("GET", url, data=payload, headers=headers)
response = response.json()
if response['Status'] == 'Success':
print('Sent message'), response['Details']
else:
print('Error:', response['Details'])
except ConnectionError as exc:
print('connection error @ failed sms')
raise self.retry(exc=exc)
except PaymentLog.DoesNotExist:
...
Also, it does not retry for the max_retries, i.e., 5 times. Can you please tell me what I am doing wrong? Or is there any better way to define a task while calling an API?
If you don't use persistent revokes your task can be executed after worker's restart. revoke has an terminate option which is False by default. If you need to kill the executing task you need to set terminate to True.
Soft, or hard? The time limit is set in two values, soft and hard . The soft time limit allows the task to catch an exception to clean up before it is killed: the hard timeout isn't catch-able and force terminates the task.
As for --concurrency celery by default uses multiprocessing to perform concurrent execution of tasks. The number of worker processes/threads can be changed using the --concurrency argument and defaults to the number of available CPU's if not set.
you hve soft_time_limit=15 seconds
, after this time celery raise SoftTimeLimitExceeded
this exeption allow you to do cleanup inside your task
from celery.exceptions import SoftTimeLimitExceeded
@celery.task(soft_time_limit=15, time_limit=20)
def mytask():
try:
return do_work()
except SoftTimeLimitExceeded:
cleanup_in_a_hurry()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With