Celery随记
1、根据任务状态执行结果不同执行不同操作
复写Task中的on_failure和on_success方法
class MyTask(Task):
def on_success(self, retval, task_id, args, kwargs):
print 'task done: {0}'.format(retval)
return super(MyTask, self).on_success(retval, task_id, args, kwargs)
def on_failure(self, exc, task_id, args, kwargs, einfo):
print 'task fail, reason: {0}'.format(exc)
return super(MyTask, self).on_failure(exc, task_id, args, kwargs, einfo)
@app.task(base=MyTask)
def add(x, y):
return x + y
2、获取任务中update_state中的meta参数,可以获取任务状态
@app.task def fft_random(n): j=0 for i in range(n): # x=random.normal(0,0.1,3000) time.sleep(1) current_task.update_state(state="PROGRESS", meta={'current': i, 'total': n}) if i==int(j*n/50): j+=1 print("j={}".format(j)) return random.random()
如果希望多个进程访问任务状态,且希望持久化任务结果,需要使用持久化的result backend,比如数据库,amqp不支持
def on_raw_message(body): print('[{0}] {1}'.format(time.time(), body)) if __name__ == '__main__': async_result = track_states.delay(2, 3) result = async_result.get(on_message=on_raw_message, propagate=False) print('Result: %s' % result)
3、任务执行完成后执行自定义回调函数
@app.task def add(x, y): return x + y def on_result_ready(result): print('Received result for id %r: %r' % (result.id, result.result,)) add.delay(2, 2).then(on_result_ready)
4、链式调用
def update_page_info(url): # fetch_page -> parse_page -> store_page chain = fetch_page.s(url) | parse_page.s() | store_page_info.s(url) chain() @app.task() def fetch_page(url): return myhttplib.get(url) @app.task() def parse_page(page): return myparser.parse_document(page) @app.task(ignore_result=True) def store_page_info(info, url): PageInfo.objects.create(url=url, info=info) #或者 fetch_page.apply_async((url), link=[parse_page.s(), store_page_info.s(url)])
链式任务中前一个任务的返回值默认是下一个任务的输入值之一 ( 不想让返回值做默认参数可以用 si() 或者 s(immutable=True) 的方式调用 )。
这里的 s()
是方法 celery.signature()
的快捷调用方式,signature 具体作用就是生成一个包含调用任务及其调用参数与其他信息的对象,个人感觉有点类似偏函数的概念:先不执行任务,而是把任务与任务参数存起来以供其他地方调用
5、根据任务ID获取任务对象
from celery.result import AsyncResult tt=AsyncResult(id='74763a23-13bd-4719-b982-7307fd708cf7')
6、任务通过date_done获取时间,默认是utc时间
修改celery.backends.base.py
查看任务的完成时间,为本地时间
数据库中存储的时间,直接修改model,celery.backends.database.models.py
数据库中存储的date_done时间为本地时间