在on_failure或on_sucesss挂钩中使用请求库会使任务无限期地重试

时间:2019-02-26 00:44:08

标签: concurrency python-requests celery django-celery

这就是我所拥有的:

import youtube_dl # in case this matters

class ErrorCatchingTask(Task):
    # Request = CustomRequest
    def on_failure(self, exc, task_id, args, kwargs, einfo):
        # If I comment this out, all is well
        r = requests.post(server + "/error_status/") 
        ....

@app.task(base=ErrorCatchingTask, bind=True, ignore_result=True, max_retires=1)
def process(self, param_1, param_2, param_3):
    ...
    raise IndexError
    ...

该工作人员将引发异常,然后貌似生成一个具有不同任务ID Received task: process[{task_id}的新任务 这是我尝试过的几件事:

  • 在其中导入from celery.worker.request import Request并覆盖on_failureon_success的功能。
  • app.conf.broker_transport_options = {'visibility_timeout': 99999999999}
  • @app.task(base=ErrorCatchingTask, bind=True, ignore_result=True, max_retires=1)
  • 关闭DEBUG模式
  • 将日志记录设置为info
  • CELERY_IGNORE_RESULT设置为false(Can I use Python requests with celery?
  • import requests as apicall排除名称空间冲突
  • 钱补丁requests Celery + Eventlet + non blocking requests
  • ErrorCatchingTask移动到单独的文件中

如果我不使用任何钩子函数,那么工作人员将只抛出异常并保持空闲状态,直到计划下一个任务为止,即使使用钩子,我也希望这样做。这是错误吗?我在github问题上一遍又一遍地搜索,但是找不到相同的问题。您如何调试这样的问题?

Django 1.11.16 芹菜4.2.1

1 个答案:

答案 0 :(得分:0)

使用grequests

后,问题得以解决

在我的情况下,在requests/adapters.py中调用conn.urlopen()时,芹菜工作者将重新安排时间。我观察到的另一种行为是,如果我在同一台计算机上打开了另一个项目中的另一个工作人员,则有时无限的重新计划将停止。这可能是最初用于其他目的的某种锁定机制。

因此,这使我怀疑这确实是线程问题,并且在研究requests库是否是线程安全的之后,我发现了一些人suggesting different things.。从理论上讲,猴子修补应具有与使用grequests类似的效果,但效果不尽相同,因此请改用grequestserequests库。

Celery调试指令为here