2013-06-20 37 views
4

今天我收到了來自Celery的錯誤電子郵件,有人可以解釋它,並可能如何解決超時問題?這將是非常有益的,謝謝。Django TimeLimitExceeded error

PS我的消息似乎已發送儘管這個錯誤,這是對的嗎?

錯誤:

Task Request to Process with id 65123935-b190-4718-9ed0-fb863359f27f 
raised exception: 
'TimeLimitExceeded(300.0,)' 


Task was called with args: (<Batch: Batch object>,) kwargs: {}. 

The contents of the full traceback was: 

Traceback (most recent call last): 
    File "/usr/local/lib/python2.7/dist-packages/billiard/pool.py", line 496, in on_hard_timeout 
    raise TimeLimitExceeded(job._timeout) 
TimeLimitExceeded: TimeLimitExceeded(300.0,) 


-- 
Just to let you know, 
py-celery at w1.ip-10-32-53-113. 

任務:

class ProcessRequests(Task): 
    name = "Request to Process" 
    max_retries = 1 
    default_retry_delay = 3 

    def run(self, batch): 
     # Only run this task on non-scheduled tasks 
     if batch.status != "Scheduled": 
      q = Contact.objects.filter(contact_owner=batch.user) 
      if batch.group == None: 
       q = q.filter(id=batch.contact_id) 
      else: 
       q = q.filter(group=batch.group) 

      for e in q: 
       msg = Message.objects.create(
        recipient_number=e.mobile, 
        content=batch.content, 
        sender=e.contact_owner, 
        billee=batch.user, 
        sender_name=batch.sender_name 
       ) 
       gateway = Gateway.objects.get(pk=2) 
       msg.send(gateway) 
+0

什麼是'msg.send()'在做什麼? – Paul

回答

1

你可以嘗試修改celeryd設置。文件應該大部分是/etc/init.d/celeryd。

CELERYD_OPTS="--time-limit==3600 -E --loglevel=DEBUG" 
+0

但這並不能解釋爲什麼我得到錯誤。 – Prometheus

+0

這是因爲超時。默認的時間限制是300秒,如果任務在這段時間後仍然運行,則會引發異常。 –

+0

看起來像在/ etc/default/celeryd中配置比在init.d文件中應用更好。 – user1914881

1

首先,您必須知道在您的任務函數/方法中獲得消息時的實際情況及其時間複雜度。如果你的任務需要超過默認的300秒完成,那麼芹菜主進程將首先發送SoftTimeLimitExceed異常,如果我們把它放在try/except塊中,你可以捕獲你的任務。如果有的話,這個例外實際上是用於清理過程。在此異常之後,芹菜會向您發送另一個異常TimeLimitExceed異常,並且它會殺死您的工作線程。

如果你啓用了芹菜設置,則相同的消息將被傳遞到另一個工人流程的後期ACK設置(這是危險的,因爲這也將失敗)。

所以,如果你得到這個例外,那麼這意味着你的任務需要超過300秒才能完成,所以調整對芹菜設置的工人,以滿足您的要求的最大時間限制。

問候,

Haridas N.

2

您會收到TimeLimitExceeded例外,因爲你的任務需要超過300秒的時間來執行。 300秒是任務可以運行的默認時間。

如回答Avichal Badaya,您可以配置芹菜允許更長的執行任務。

你提到你的消息還是發出去了,但這種情況發生,因爲你的任務是爲一個批次寫的。因此,無論您是試圖發送多封郵件,還是隻嘗試發送一封郵件,但一些郵件的批次都是如此混亂。

你能告訴我們你怎麼稱呼這項任務嗎?

1

您正在使用msg.send(gateway)發送消息給手機,對不對?

在此方法中,你要連接到遠程Web服務,這實際上發送消息,對不對?

之後,可能已發送的郵件,但你給對方的連接沒有被關閉,儘管Web服務應該關閉它,發送消息,併爲您的請求的響應之後。

的最後一件事 - 你有沒有做了以下創建用於與Web服務連接套接字之前:

import socket 
socket.setdefaulttimeout(seconds) # seconds argument is of type float 

這樣一來,你的任務是掛在插座無限的時間等待Web服務發送響應和/或關閉連接。其實it would wait forever, if not interrupted by celery timeout

默認套接字超時值是None作爲文檔指出 http://docs.python.org/2/library/socket.html#socket.setdefaulttimeout

希望這是有幫助的。