2016-05-25 16 views
2

我的問題:我有一個延期與回調和errbacks。我需要在特定的errback後停止進程。換句話說,如果調用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) 

此代碼是一個簡單的版本,而不是反映我所需要的。之後-A-過程中,我需要baypass -B-和-C-,並在結束時,反應是「0,埃羅」,而不是「1,確定」

我現在的回報:

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 

我怎樣才能做到這一點

在此先感謝

+0

這是一個非常好的問題,我很想聽聽有沒有人回答這個問題。這裏有一些關於這個問題的有趣討論:http://stackoverflow.com/questions/9295359/stopping-twisted-from-swallowing-exceptions我不知道你想做什麼是可能的。基本上如果你想完全停止執行,你爲什麼要返回errback的結果?也許你可以簡單地在errback中引發錯誤?這將停止處理。如果你不提出錯誤Twisted假定你想繼續前進,並繼續前進。 –

+0

我正在使用回調鏈來控制和驗證http請求(REST Web服務調用)的結果。當結果是我所期望的時候,這個過程繼續下去。如果沒有,我提出失敗調用errback(一種返回修改響應的方法)。但是,如果在一個調用失敗的順序中,以下是不相關的。謝謝@PawelMiech提示。 –

回答

0

這是一個非常有趣的疑問句?灰。 Twisted在發生錯誤後不給出任何記錄的API來修改回調鏈。如果你真的想在errback中中斷處理,你總是可以引發錯誤而不是陷入它。

但是,如果您確實想在特定條件下從延期中刪除所有回調,則可以使用簡單的破解。回調被保留在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。工作正常。 –