2017-06-29 27 views
0

documentation意味着如果連接因任何原因而下降,應該通知Deferredrequest.notifyFinish()。我裝類似如下代碼:Twisted.web.server不通知客戶端是否取消連接

from twisted.web.resource import Resource 
from twisted.web.server import NOT_DONE_YET 
from twisted.internet import reactor 
from twisted.logger import Logger 

log = Logger() 

class DelayedResource(Resource): 
    isLeaf = 1 

    def _delayedRender(self, request): 
     log.info("Rendered!") 
     request.write("<html><body>Sorry to keep you waiting.</body></html>") 
     request.finish() 

    def _responseFailed(self, err, call): 
     call.cancel() 
     log.info("No. Wait. Stop") 

    def render_GET(self, request): 
     log.info("Lets try this!") 
     call = reactor.callLater(5, self._delayedRender, request) 
     request.notifyFinish().addErrback(self._responseFailed, call) 
     return NOT_DONE_YET 

如果我取消來自客戶端的連接,_responseFailed不會被調用。日誌語句「No Wait。Stop」永遠不會被打印,並且「渲染!」陳述印刷。

這很重要,因爲在我的真實使用情況下,我分配的資源需要在連接斷開時解除分配。升級到扭曲17.1.0後,這些停止清理。

我做錯了嗎?或者這是一個扭曲的錯誤?

+0

如果你完成了你的代碼片段,那它將是一件好事,因此它是一個獨立的可運行示例。而且,這個功能對我來說很難理解。 –

+0

@ Jean-PaulCalderone您是說這是Twisted或OP的代碼中的一箇中斷功能嗎?我注意到過去類似的東西,並認爲瀏覽器或操作系統正在做某些事情,而不是斷開連接。 –

+0

優勢的證據指向一個扭曲的錯誤,這是一個惱人的標籤「不會修復」https://twistedmatrix.com/trac/ticket/8692 –

回答

1

這是由於由http://tm.tl/8320引入的錯誤(或意外引入的功能 - 您是裁判!),但最近由http://tm.tl/8692修復。因此,扭曲16.3到扭曲17.5不會觸發notifyFinish()Failure(雖然它似乎仍然在成功情況下觸發)。由於HTTP實現和TCP的基本特性的複雜性,在HTTP客戶端觀察到某種錯誤的情況下,甚至在該範圍外的Twisted版本可能不會始終激活notifyFinish()Failure。請牢記這一點,並確保在請求結束時發生的任何處理都不依賴此Deferred上的errback(即還附加回調或確保處理作爲響應的一部分運行代碼)。

+0

版本帖子Twisted 17.5應該是固定的?好。除了17.5是目前最高版本。我想答案是「等到下一個扭曲的版本」。 –

+0

確實。雖然,爲了安全起見,還可以測試master @ HEAD並驗證實施的修補程序是否實際提供了所需的行爲(然後,如果沒有,請在下一個發行版之前投訴:)。 –

相關問題