2011-03-08 38 views
0

背景如何從LoopingCall

我最近一直在那裏扭用一個項目的一部分內停止TimerService。我們利用TimerService來守護進程。是的,我意識到這種方法可能已經過度殺傷,但我們正在努力保持一致,並使用經過驗證的框架。昨天,在LoopingCall中導致TimerService失敗的異常未處理,但扭曲的應用程序仍在運行(請參閱twisted enhancement request)。爲了避免這種情況,我們希望在一個catch-all異常處理程序結束時停止服務。

問題

如何同時停止TimerService從LoopingCall調用方法中的twistd來申請?我擔心的是,當TimerService無法處理異常時,即使TimerService不再循環,linux進程仍會繼續運行。

例如:


def some_callable(): 
    try: 
    # do stuff 
    except SomeSpecificError ex: 
    # handle & log error 
    except SomeOtherSpecificError ex: 
    # handle & log error 
    except: 
    # log sys.exc_info() details 
    # stop service. 

注意:以下內調用不起作用。


from twisted.internet import reactor 
reactor.stop() 

回答

5

開始之前你不能停止反應堆:

>>> from twisted.internet import reactor 
>>> reactor.stop() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/home/exarkun/Projects/Twisted/branches/simplify-ssl-4905/twisted/internet/base.py", line 570, in stop 
    "Can't stop reactor that isn't running.") 
twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running. 
>>> 

然而,只要反應器已經在運行,reactor.stop正常工作:

>>> from twisted.internet import reactor 
>>> reactor.callLater(3, reactor.stop) 
<twisted.internet.base.DelayedCall instance at 0xb762d2ec> 
>>> reactor.run() 
[... pause ...] 
>>> 

TimerService是一個圍繞LoopingCall的包裝。更具體地說,當它開始LoopingCall時,它通過now=Truerun。這會導致函數立即被第一次調用,而不是在指定的時間間隔過去一次之後調用。

所以當調用TimerService.startService時,你的函數被調用。而反應堆還沒有運行。在第一次調用你的函數時,你不能停止反應堆,因爲它還沒有啓動。

這個程序:

from twisted.application.internet import TimerService 

def foo(): 
    from twisted.internet import reactor 
    reactor.stop() 

from twisted.application.service import Application 

application = Application("timer stop") 
TimerService(3, foo).setServiceParent(application) 

產生這些結果:

[email protected]:/tmp$ twistd -ny timerstop.tac 
2011-03-08 11:46:19-0500 [-] Log opened. 
2011-03-08 11:46:19-0500 [-] using set_wakeup_fd 
2011-03-08 11:46:19-0500 [-] twistd 10.2.0+r30835 (/usr/bin/python 2.6.4) starting up. 
2011-03-08 11:46:19-0500 [-] reactor class: twisted.internet.selectreactor.SelectReactor. 
2011-03-08 11:46:19-0500 [-] Unhandled Error 
     Traceback (most recent call last): 
      File "/home/exarkun/Projects/Twisted/branches/simplify-ssl-4905/twisted/application/service.py", line 277, in startService 
      service.startService() 
      File "/home/exarkun/Projects/Twisted/branches/simplify-ssl-4905/twisted/application/internet.py", line 284, in startService 
      self._loop.start(self.step, now=True).addErrback(self._failed) 
      File "/home/exarkun/Projects/Twisted/branches/simplify-ssl-4905/twisted/internet/task.py", line 163, in start 
      self() 
      File "/home/exarkun/Projects/Twisted/branches/simplify-ssl-4905/twisted/internet/task.py", line 194, in __call__ 
      d = defer.maybeDeferred(self.f, *self.a, **self.kw) 
     --- <exception caught here> --- 
      File "/home/exarkun/Projects/Twisted/branches/simplify-ssl-4905/twisted/internet/defer.py", line 133, in maybeDeferred 
      result = f(*args, **kw) 
      File "timerstop.py", line 5, in foo 
      reactor.stop() 
      File "/home/exarkun/Projects/Twisted/branches/simplify-ssl-4905/twisted/internet/base.py", line 570, in stop 
      "Can't stop reactor that isn't running.") 
     twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running. 

然而,這一個正常工作:

from twisted.application.internet import TimerService 

counter = 0 

def foo(): 
    global counter 
    if counter == 1: 
     from twisted.internet import reactor 
     reactor.stop() 
    else: 
     counter += 1 

from twisted.application.service import Application 

application = Application("timer stop") 
TimerService(3, foo).setServiceParent(application) 

而且略顯不足嚴重,那麼,這一個:

from twisted.application.internet import TimerService 

def foo(): 
    from twisted.internet import reactor 
    reactor.callWhenRunning(reactor.stop) 

from twisted.application.service import Application 

application = Application("timer stop") 
TimerService(3, foo).setServiceParent(application) 
+0

這真是一個很好的答案,夥計。非常感謝你的幫助! – bitcycle 2011-03-08 17:03:32