Twisted.web.server不通知客户端是否取消连接
documentation意味着如果连接因任何原因而下降,应该通知Deferred
在request.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后,这些停止清理。
我做错了吗?或者这是一个扭曲的错误?
这是由于由http://tm.tl/8320引入的错误(或意外引入的功能 - 您是裁判!),但最近由http://tm.tl/8692修复。因此,扭曲16.3到扭曲17.5不会触发notifyFinish()
与Failure
(虽然它似乎仍然在成功情况下触发)。由于HTTP实现和TCP的基本特性的复杂性,在HTTP客户端观察到某种错误的情况下,甚至在该范围外的Twisted版本可能不会始终激活notifyFinish()
和Failure
。请牢记这一点,并确保在请求结束时发生的任何处理都不依赖此Deferred
上的errback(即还附加回调或确保处理作为响应的一部分运行代码)。
版本帖子Twisted 17.5应该是固定的?好。除了17.5是目前最高版本。我想答案是“等到下一个扭曲的版本”。 –
确实。虽然,为了安全起见,还可以测试master @ HEAD并验证实施的修补程序是否实际提供了所需的行为(然后,如果没有,请在下一个发行版之前投诉:)。 –
如果你完成了你的代码片段,那它将是一件好事,因此它是一个独立的可运行示例。而且,这个功能对我来说很难理解。 –
@ Jean-PaulCalderone您是说这是Twisted或OP的代码中的一个中断功能吗?我注意到过去类似的东西,并认为浏览器或操作系统正在做某些事情,而不是断开连接。 –
优势的证据指向一个扭曲的错误,这是一个恼人的标签“不会修复”https://twistedmatrix.com/trac/ticket/8692 –