Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如果它';的子任务给出了一个异常_Python_Django_Rabbitmq_Celery - Fatal编程技术网

Python 如果它';的子任务给出了一个异常

Python 如果它';的子任务给出了一个异常,python,django,rabbitmq,celery,Python,Django,Rabbitmq,Celery,我在芹菜方面遇到了一个非常奇怪的问题: 有一个任务链,其中一个任务给出一个异常,并进行多次重试 chain = (err.si(1) | err.si(2)) result = chain.apply_async() result.state result.get() 以下是任务的代码: @celery.task(base=MyTask) def err(x): try: if x < 3: raise Exception else: re

我在芹菜方面遇到了一个非常奇怪的问题:

有一个任务链,其中一个任务给出一个异常,并进行多次重试

chain = (err.si(1) | err.si(2))
result = chain.apply_async()
result.state
result.get()
以下是任务的代码:

@celery.task(base=MyTask)
def err(x):
try:
    if x < 3:
        raise Exception
    else:
        return x+1

except Exception as exp:
    print "retrying"
    raise err.retry(args=[x],exc=exp,countdown=5,max_retries=3)
但,尽管单独执行的任务被标记为失败,但在链中执行会得到相同的结果-挂起和冻结的get

我预计一旦它的任何任务失败,该链就会失败。获取结果应该会产生从该任务引发的异常

_更新 由apply\u async提供的堆栈跟踪,且始终\u EAGER=True

result = chain.apply_async()

Exception                                 
Traceback (most recent call last)
<ipython-input-4-81202b369b5f> in <module>()
----> 1 result = chain.apply_async()

lib/python2.7/site-packages/celery/canvas.pyc in apply_async(self, args, kwargs,     **options)
    147         # For callbacks: extra args are prepended to the stored args.
    148         args, kwargs, options = self._merge(args, kwargs, options)
--> 149         return self.type.apply_async(args, kwargs, **options)
    150 
    151     def append_to_list_option(self, key, value):

/lib/python2.7/site-packages/celery/app/builtins.pyc in apply_async(self, args, kwargs, group_id, chord, task_id, **options)
    232                 task_id=None, **options):
    233             if self.app.conf.CELERY_ALWAYS_EAGER:
--> 234                 return self.apply(args, kwargs, **options)
    235             options.pop('publisher', None)
    236             tasks, results = self.prepare_steps(args, kwargs['tasks'])

lib/python2.7/site-packages/celery/app/builtins.pyc in apply(self, args, kwargs, subtask, **options)
    249             last, fargs = None, args  # fargs passed to first task only
    250             for task in kwargs['tasks']:
--> 251                 res = subtask(task).clone(fargs).apply(last and (last.get(), ))
    252                 res.parent, last, fargs = last, res, None
    253             return last

lib/python2.7/site-packages/celery/result.pyc in get(self, timeout, propagate, **kwargs)
    677         elif self.state in states.PROPAGATE_STATES:
    678             if propagate:
--> 679                 raise self.result
    680             return self.result
    681     wait = get

Exception: 
result=chain.apply\u async()
例外情况
回溯(最近一次呼叫最后一次)
在()
---->1结果=chain.apply\u async()
apply_async中的lib/python2.7/site-packages/芹菜/canvas.pyc(self、args、kwargs、**选项)
147#对于回调:在存储的参数前面加上额外的参数。
148 args,kwargs,options=self.\u merge(args,kwargs,options)
-->149返回self.type.apply_async(args、kwargs、**选项)
150
151 def附加到列表选项(self、key、value):
/apply_async中的lib/python2.7/site-packages/celery/app/builtins.pyc(self、args、kwargs、group_id、chord、task_id、**选项)
232任务id=无,**选项):
233如果self.app.conf.芹菜总是渴望:
-->234返回自应用(args、kwargs、**选项)
235选项。pop('publisher',无)
236个任务,结果=自我准备步骤(args,kwargs['tasks'))
lib/python2.7/site-packages/芹菜/app/builtins.pyc在apply中(self、args、kwargs、子任务,**选项)
249 last,fargs=None,args#fargs只传递给第一个任务
250用于kwargs[‘任务’]格式的任务:
-->251 res=子任务(task).clone(fargs).apply(last和(last.get(),))
252 res.parent,last,fargs=last,res,None
253最后返回
get中的lib/python2.7/site-packages/芹菜/result.pyc(self、timeout、propagate、**kwargs)
677 elif self.state in states.u states:
678如果传播:
-->提高自己的成绩
680返回自我结果
681等待=得到
例外情况:

事实上,我认为你不应该在这里使用
raise

当发生异常时,您可能只想使用
err.retry
,而不是
raise err.retry
,当您有一个链时:

>>> c = a.s() | b.s() | c.s()
>>> res = c()
>>> res.get()
调用链将为链中的所有任务生成唯一id,发送消息并返回链中的最后一个结果

因此,当您执行
res.get()
时,您只需尝试检索链中最后一个任务的结果

它还将使用
parent
属性装饰结果,您可以遍历这些属性以获得链的进度:

>>> res                # result of c.s()
>>> res.parent         # result of b.s()
>>> res.parent.parent  # result of a.s()
如果您想检查过程中的错误,可以执行以下操作:

def nodes(node):
    while node.parent:
        yield node
        node = node.parent
    yield node


values = [node.get(timeout=1) for node in reversed(list(nodes(res)))]
value = values[-1]

尝试在激活CELERY\u ALWAYS\u Earge的情况下运行任务,这将有助于找出导致问题的原因。如果我将CELERY\u ALWAYS\u Earge设置为True,则apply\u async会立即给出堆栈跟踪,结果变量为None。如果我将其设置为false,则结果确实存在,result.state=Pending。此文档是旧文档。Task.retry实际上总是引发异常。异常是在worker中专门处理的,因此它知道将重试该任务。当人们不知道代码会上升,并且认为代码会继续下去时,它会使代码更难阅读。因此,文档被改为使用“raise err.retry”。你不需要加薪,但这给了读者一个提示,它不会继续。从技术上来说,这是一个综合测试,我想处理可能发生的异常。我的任务与外部Web服务交互,这些外部Web服务不稳定,可能会返回意外的输出。请回答asksol!如果子任务的父任务失败(引发异常),是否有任何常规方法阻止子任务执行?示例设置:chord(组(parent1,parent2),组(children))如果parent1失败,它的子项将以[exception,parent2.retval]作为第一个参数执行,这是我想要避免的。只有chord通过传递异常值以这种方式工作,文档中没有指定这种行为。我认为,通过不执行chord回调使其与其余部分保持一致是有意义的。也许你可以在这里提出一个问题:?
def nodes(node):
    while node.parent:
        yield node
        node = node.parent
    yield node


values = [node.get(timeout=1) for node in reversed(list(nodes(res)))]
value = values[-1]