任务选项可以阻止任务在芹菜弦中运行

时间:2017-07-26 20:55:42

标签: celery celery-task chord

我正在尝试将现有的芹菜组调用转换为和弦以防止死锁。以前的代码有重试和到期时间。我设法让没有这些设置的和弦工作,但当我尝试应用设置时,我没有看到正在运行的任务。我没有在文档中看到有关在和弦上应用相同设置的任何内容。我正在运行芹菜版3.1.6。

上一个代码:

jobs = group([reset_device.s(topoid, dev_list[i], 
              waittime_list[i], skipflag) for i in range(len(dev_list))]
              ).apply_async(expires=waittime, retry=True, retry_policy={
                                                    'max_retries': 3,
                                                    'interval_start': 0.5,
                                                    'interval_step': 0.2,
                                                    'interval_max': 0.2})
results = jobs.join_native(timeout=waittime + 600, propagate=True)

工作和弦(没有设置):

jobs = chord([reset_device.s(topoid, dev_list[i], 
              waittime_list[i], skipflag) for i in range(len(dev_list))])(callback)

非工作和弦#1:

jobs = chord([reset_device.s(topoid, dev_list[i], waittime_list[i],
             skipflag).set(expires=datetime.now() + timedelta(seconds=waittime)).set(retry=True).set(retry_policy=retry_policy)
              for i in range(len(dev_list))])(callback)

非工作和弦#2

jobs = chord([reset_device.subtask(args=(topoid, dev_list[i], waittime_list[i],skipflag), 
              expires=datetime.now()+timedelta(seconds=waittime), retry=True, retry_policy=retry_policy) 
             for i in range(len(dev_list))])(callback)

在#1和#2两种情况下,和弦中的任务似乎都没有运行。 如何应用到期时间并重试和弦中调用的每个任务?

1 个答案:

答案 0 :(得分:1)

我想出来了,这是一堆问题。

第一个问题是expires字段不接受一个整数,只接受一个和弦内的日期时间对象(可能也是组和链),尽管文档没有任何区别。这已在以后的版本中修复,我使用3.1.25测试并且能够验证修复。

第二个问题是芹菜3.1.6不记录和弦内的错误(我认为群组和链也是如此)。这也已经修复,我在3.1.25中测试过并且能够看到失败。

第三个问题与错误消息有关:

[2017-08-07 18:39:56,043: ERROR/Worker-5] Chord '98246849-0d5d-4be2-85e3-3fc08e90011d' raised: TaskRevokedError(u'expired',)
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/celery/app/builtins.py", line 90, in unlock_chord
ret = j(timeout=3.0, propagate=propagate)
  File "/usr/local/lib/python2.7/dist-packages/celery/result.py", line 691, in join_native
raise value
TaskRevokedError: expired

这是因为时区不对。我使用了datetime.now()代替datetime.utcnow(),这解决了问题并在3.1.6中有效。

或者我可以设置celery config CELERY_ENABLE_UTC = False,默认情况下设置为True。这让我感到困惑,因为我们已将config CELERY_TIMEZONE设置为当地时间。 expires字段与datetime对象一起使用时,使用本地时间或UTC,具体取决于CELERY_ENABLE_UTC设置的值。我建议保持两个配置设置相同。

有趣的是,创建了回调函数并进行轮询,以查看和弦是否完成,尽管和弦任务从未执行过,它只是永远停留在那里。我相信这may have been fixed in celery 4.1