2012-12-28 123 views
2

管理connectionLost我寫下面的代碼段來處理扭曲連接丟失:如何適當地扭曲

class Foo(LineReceiver): 
    def connectionLost(self, reason): 
     if reason.type != ConnectionLost: 
      reactor.stop() 
    def terminate(self): 
     self.transport.loseConnection() 

terminate方法由一些輸入/輸出協議調用。 我必須在connectionLost方法中測試reason.type以避免出現錯誤 '當我用Ctrl-C中斷我的程序而不是調用terminate方法的 '時,無法停止不運行的反應器。

此代碼的工作原理,但我想知道是否有一個更優雅的方式來管理扭曲的連接結束? 謝謝!

回答

2

你面臨的問題是,控制 + Ç被調用時停止該反應器已經安裝的信號處理程序。反應器在停止時調用您的方法,因爲關閉反應器會自動關閉所有連接。反過來,你的協議試圖停止反應堆 - 只發現它已經停止!

一個簡單(但並不完全正確)的方式來避免這種情況是看反應器上的running屬性停止它之前,像這樣:

def connectionLost(self, reason): 
    if reactor.running: 
     reactor.stop() 

(另請注意,你可能不應該請檢查異常類型;您可能想要使用Failure.check代替,如果您真的關心原因的類型,但在大多數情況下您不應該關心原因的類型;斷開的連接只是斷開的連接,除非你試圖確定某個特定的破壞屬性,例如終端是否應該導致SSL會話終止。)

如果您希望更全面地檢查此問題,您需要通過"before", "shutdown" system event trigger監測反應堆的狀態,或使用Twisted 12.3中介紹的twisted.internet.task.react API

+1

它實際上比這更難解決。特別是'running'屬性非常混亂,大多數人不正確地使用它。這是爲什麼Twisted 12.3引入'twisted.internet.task.react' API的很大一部分。 –

+0

更新了我的答案,以提到解決方案這個解決方案的不太正確的性質,並添加了一些其他選項。 – Glyph

+0

Glyph and Jean-Paul,非常感謝 – jean