我正在使用Celery使用结构设置远程服务器。
因此,我想将Server.status更改为">正在启动"(以防止双重启动(,并在出现问题时将Server.status更改为"错误"。请查看我的代码:
class ChangeBackStatusOnErrorTask(celery.Task):
abstract = True
def on_failure(self, exc, task_id, args, kwargs, einfo):
print 'from on_failue', self, exc, task_id, args, kwargs, einfo
return
#server = Server.query.get(server_id)
#server.status = RemoteStatus.ERROR
#db.session.commit()
@celery.task(bind=True, base=ChangeBackStatusOnErrorTask)
def deploy_server(self, server_id):
"""To prevent launching while we are launching, we will
disable launching until the server's status is LAUNCHED
"""
server = Server.query.get(server_id)
if not server.can_launch():
return
try:
server.status = RemoteStatus.LAUNCHING
db.session.commit()
host = server.ssh_user + '@' + server.ip
execute(fabric_deploy_server, self, server, hosts=host)
server.status = RemoteStatus.LAUNCHED
db.session.commit()
except Exception as e:
server.status = RemoteStatus.ERROR
db.session.commit()
traceback.print_exc()
raise e
但是,当我为我的芹菜任务提供错误的 IP 地址时,我能够遇到绕过所有故障处理机制的异常:
[2017-07-17 03:58:07,077: WARNING/PoolWorker-7] [root@1.2.3.45] Executing task 'fabric_deploy_server'
[2017-07-17 03:58:07,078: WARNING/PoolWorker-7] [root@1.2.3.45] sudo: apt-get update
[2017-07-17 03:58:17,173: WARNING/PoolWorker-7] Fatal error: Timed out trying to connect to 1.2.3.45 (tried 1 time)
Underlying exception:
timed out
[2017-07-17 03:58:17,173: WARNING/PoolWorker-7] Aborting.
[2017-07-17 03:58:22,172: ERROR/MainProcess] Task handler raised error: WorkerLostError('Worker exited prematurely: exitcode 0.',)
Traceback (most recent call last):
File "/Users/vng/.virtualenvs/AutomataHeroku/lib/python2.7/site-packages/billiard/pool.py", line 1224, in mark_as_worker_lost
human_status(exitcode)),
WorkerLostError: Worker exited prematurely: exitcode 0.
如您所见,
ChangeBackStatusOnErrorTask.on_failure
没有被叫到。- 这个例外逃脱了我的尝试/捕获集团。
如何捕获此错误?我需要将服务器状态设置为错误,以便我可以重新启动我的任务。
从文档中,您应该从celery.execute
中获取一个celery.result.EagerResult
对象,因此即使它失败了,我认为除非您告诉它,否则它不会引发错误。我认为你也不需要传递自我来执行。
执行似乎也来自芹菜2,你真的应该考虑更新。
试一试。
try:
server.status = RemoteStatus.LAUNCHING
db.session.commit()
host = server.ssh_user + '@' + server.ip
# Apply will run locally.
# http://docs.celeryproject.org/en/2.1-archived/reference/celery.execute.html#executing-tasks-celery-execute
# Throw=True will re-raise the error if you get one.
result = execute.apply(fabric_deploy_server, server, hosts=host, throw=True)
server.status = RemoteStatus.LAUNCHED
db.session.commit()
except Exception as e:
server.status = RemoteStatus.ERROR
db.session.commit()
traceback.print_exc()
raise e
芹菜执行 http://docs.celeryproject.org/en/2.1-archived/reference/celery.execute.html#executing-tasks-celery-execute
芹菜渴望结果 http://docs.celeryproject.org/en/2.1-archived/reference/celery.result.html#celery.result.EagerResult