检查当前正在运行的Celery任务会发现一个奇怪的time_start
时间戳:
>> celery.app.control.inspect().active()
{u'celery@worker.hostname': [{u'acknowledged': True,
u'args': u'(...,)',
u'delivery_info': {u'exchange': u'celery',
u'priority': 0,
u'redelivered': None,
u'routing_key': u'celery'},
u'hostname': u'celery@worker.hostname',
u'id': u'3d92fdfd-524e-4ba1-98cb-cf83af2ad8e9',
u'kwargs': u'{}',
u'name': u'task_name',
u'time_start': 9636801.218162088,
u'worker_pid': 7931}]}
time_start
属性将任务重新定为 1970 (在创建Celery,Python之前,我没有自定义的DeLorean):
>> from datetime import datetime
>> datetime.fromtimestamp(9636801.218162088)
datetime.datetime(1970, 4, 22, 13, 53, 21, 218162)
我是否误解了time_task
属性?我的Celery应用程序配置错误了吗?
我在Linux上使用带有Django应用程序和Redis后端的Celery 3.1.4。
任务由执行的工作程序运行,如下所示:
./manage.py celery worker --loglevel=INFO --soft-time-limit=600 --logfile=/tmp/w1.log --pidfile=/tmp/w1.pid -n 'w1.%%h'
答案 0 :(得分:29)
我通过挖掘Celery和Kombu代码找到了我自己问题的答案:任务的time_start
属性由kombu.five.monotonic
函数计算。 (具有讽刺意味的是,kombu代码也引用另一个StackOverflow question作为参考)该函数返回的时间戳是指"单调"由clock_gettime
系统调用计算的时间。
如clock_gettime
documentation中所述,此单调时间表示经过的时间"因为某些未指定的起点"。此功能的目的是确保时间随着其他时钟值的变化而单调增加。
因此,为了获得任务开始的实际日期时间,我们只需要将time_start
属性与单调时钟的当前值进行比较:
>> from datetime import datetime
>> from time import time
>> import kombu.five
>> datetime.fromtimestamp(time() - (kombu.five.monotonic() - 9636801.218162088))
datetime.datetime(2013, 11, 20, 9, 55, 56, 193768)
编辑:检查报告的time_start
属性不再是单调的:https://github.com/celery/celery/pull/3684我花了四年的时间才写出正确的拉取请求0: - )