2016-05-25 5 views
2

問題:私はコールバックとエラーバックを持っています。特定のエラーの後にプロセスを停止する必要があります。言い換えれば、errbackの特定の関数が呼び出された場合、その戻り値を取得する必要があり、次のコールバックを処理しないでください。Twisted:遅延時のコールバックチェーンを中断する方法

from twisted.internet import defer 
from twisted.python import failure, util 


class Test (object): 

@classmethod 
def handleFailure(self, f): 
    print "handleFailure" 
    f.trap(RuntimeError) 
    return '0', 'erro' 

@classmethod 
def handleResult(self, result, message): 
    print "handleResult of %s. Old results %s, %s: " % (message, result[0], result[1]) 
    return 1, 'ok' 

@classmethod 
def doFailure (self, result, message): 
    print "handleResult of %s. Old results %s, %s: " % (message, result[0], result[1]) 
    raise RuntimeError, "whoops! we encountered an error" 


@classmethod 
def deferredExample(self): 
    d = defer.Deferred() 
    # 1o. call without error 
    d.addCallback(Test.handleResult, 'call 1') 
    # 2o. call without error 
    d.addCallback(Test.handleResult, 'call 1') 
    # 3o. call causes the failure 
    d.addCallback(Test.doFailure, 'call 3') 
    # the failure calls the error back 
    d.addErrback (Test.handleFailure) # - A - 
    # after error back, the next call back is called 
    d.addCallback(Test.handleResult, 'call 4') # - B - 
    # and the last call back is called 
    d.addCallback(Test.handleResult, 'call 5') # - C - 

    d.callback("success") 
    return d.result[0], d.result[1] 

if __name__ == '__main__': 
# behindTheScenes("success") 
    print "\n-------------------------------------------------\n" 
    global num; num = 0 
    tst = Test() 
    rtn1, rtn2 = tst.deferredExample() 
    print "RTN: %s %s" % (rtn1, rtn2) 

このコードは、私が必要とするものを反映した単純なバージョンです。 「、「1、OKではない-A-プロセスの後、私は-B-と-C-をbaypassする必要があり、そして最後に、応答が "0、ERRO" で

私の現在のリターン:。

handleResult of call 1. Old results s, u: 
handleResult of call 1. Old results 1, ok: 
handleResult of call 3. Old results 1, ok: 
handleFailure 
handleResult of call 4. Old results 0, erro: 
handleResult of call 5. Old results 1, ok: 
RTN: 1 ok 

と私がしたい:

handleResult of call 1. Old results s, u: 
handleResult of call 1. Old results 1, ok: 
handleResult of call 3. Old results 1, ok: 
handleFailure 
RTN: 0 erro 

私はこれを行うことができますどのように本当に面白いQUESです事前

+0

本当に良い質問ですが、誰かがこれに答えるのを聞いて欲しいです。この問題に関するいくつかの興味深い議論がここにあります:http://stackoverflow.com/questions/9295359/stopping-twisted-from-swallowing-exceptions私はあなたがしたいことが可能かどうかは分かりません。基本的に、実行を完全に停止したい場合は、なぜエラーバックからの結果を返すのですか?たぶんあなたは単にエラーバックでエラーを出すことができますか?これで処理が停止します。あなたがエラーを起こさないなら、Twistedはあなたが移動したいと仮定し、それは動く。 –

+0

私は、コールバックチェーンを使用して、http getリクエスト(REST Webサービスコール)の結果を制御して検証しています。結果が私の期待通りであれば、プロセスは続行されます。そうでない場合は、errback(レスポンスを変更したメソッドを呼び出す)に失敗します。しかし、一連の呼び出しで失敗した場合、以下は無関係です。先端に感謝@PawelMiech。 –

答えて

0

のおかげ? 。 Twistedは、エラーが発生した後にコールバックチェーンを変更するためのAPIを提供していません。本当にerrbackで処理を中断したいのであれば、それをトラッピングするのではなくエラーを発生させることができます。

しかし、特定の条件ですべてのコールバックをDeferredから削除したい場合は、簡単なハックを使用できます。コールバックは、単純オブジェクト属性としてDeferredに保持されます。https://github.com/twisted/twisted/blob/twisted-16.2.0/twisted/internet/defer.py#L288この属性を空のリストにリセットするだけですべてのコールバックが削除され、処理が停止されます。

@classmethod 
def handleFailure(self, f, d): 
    print "handleFailure" 
    f.trap(RuntimeError) 
    d.callbacks = [] 
    return '0', 'erro' 

これは機能したいと思っていますが、ややハッキリなので、他のユーザーの意見を読んでいただければ幸いです。この問題に関する議論がここにあります:Stopping Twisted from swallowing exceptionsここでの議論は、あなたがしようとしていることは、Twistedの精神に反していることを示唆しています。

+0

ありがとう@PawelMiech。正常に動作します。 –

関連する問題