Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Celery task getting SoftTimeLimitExceeded calling API

I have two tasks, where I need to call two different API to send a SMS and an email.

views.py

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()

tasks.py

@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?

like image 319
Benjamin Smith Max Avatar asked Jul 12 '18 16:07

Benjamin Smith Max


People also ask

How do I stop Celery task?

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.

What is a soft time limit?

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.

What is concurrency in Celery?

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.


1 Answers

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()
like image 149
Ryabchenko Alexander Avatar answered Sep 27 '22 20:09

Ryabchenko Alexander