Python 如何预防';IOError:无法写入数据';客户端何时关闭与Django/WSGI应用程序的连接?

Python 如何预防';IOError:无法写入数据';客户端何时关闭与Django/WSGI应用程序的连接?,python,django,apache,mod-wsgi,django-piston,Python,Django,Apache,Mod Wsgi,Django Piston,我有一个iPhone应用程序,它使用Python实现的web服务,使用Django和活塞,通过WSGI在apache服务器上运行 有时,应用程序会在通话结束前关闭与服务器的连接。当它这样做时,会导致: [Tue Sep 06 11:29:46 2011] [error] [client 207.35.164.99] mod_wsgi (pid=820): Exception occurred processing WSGI script 'myscript.wsgi'. [Tue Sep 06

我有一个iPhone应用程序,它使用Python实现的web服务,使用Django和活塞,通过WSGI在apache服务器上运行

有时,应用程序会在通话结束前关闭与服务器的连接。当它这样做时,会导致:

[Tue Sep 06 11:29:46 2011] [error] [client 207.35.164.99] mod_wsgi (pid=820): Exception occurred processing WSGI script 'myscript.wsgi'.
[Tue Sep 06 11:29:46 2011] [error] [client 207.35.164.99] IOError: failed to write data
显示在我的服务器的错误日志中

我可以通过不显式关闭连接来“修复”应用程序中的问题,而只是让它完成下载并忽略结果。但是,如果可能的话,我想在服务器端解决这个问题。我该怎么做?

[免责声明:这是一个“为什么不容易做到”的解释,而不是一个解决方案]

正如@Slott所指出的,在关闭的套接字上调用
stream.close
stream.write
时,这绝对是技术上正确的行为。然而,我理解这个问题的动机。。。在wsgi应用程序的上下文中,客户端在完全或部分读取后终止连接不是“异常”行为,它总是发生。对于未处理的代码,会给人留下意外的印象/代码对此毫无准备,而事实上这是意料之中的,不值得注意。所以修理一下就好了

问题是你必须找到一种区分案例的方法

  • 类似“客户端读取”状态:304,然后关闭连接”或“客户端读取所有字节,然后关闭连接,即使它请求的连接应该被重用”的情况下,除了调用
    log.debug()
    之外,最好不要发出任何类型的日志记录

  • 但是“客户端在文件中间停止读取,因为ISP路由器有一个笔划连接死了”这样的情况是值得记录的。某些操作未成功完成,服务器应用程序构建的任何事务状态都应回滚。在这种情况下,向上传播是正确的做法

只有在每一个可能出现错误的地方修改代码以区分这两种情况,这样的错误才是可以沉默的。在那之前,wsgi的作者似乎在谨慎方面犯了错误。因此,据我所知,没有一个快速解决方法


(另外,我应该注意,这不是django特有的,我使用粘贴+挂架,并让同样的事情发生)

请参见:

如果正在处理iterable,则消息记录了调试级别,并且没有 使用Python异常。这样就可以看到客户端关闭连接的问题 使用iterable时,需要调试LogLevel


显然,您需要将Django响应调整为一个iterable而不是字符串。

Um。这不是一个“错误”。这更像是事实。应用程序关闭了连接。事实记录在“错误”级别,以便可见。你不喜欢这里面的什么?服务器记录这一点是因为这是一个关于连接的事实。我不喜欢它的一点是它经常发生,并且它正在填充我的日志:)我不希望它被记录,或者至少不作为错误记录。你还在使用mod_wsgi 2.X吗?mod_wsgi的3.X版并没有那么吵闹。你的意思是你在mod_wsgi 3.X上。WSGI是一个规范,其版本有1.0和1.0.1。另一方面,mod_wsgi是wsgi规范的一个实现。使用专有名称很有帮助,有时会引起混淆。谢谢你的提示。例外似乎来自活塞(我正在使用的python库)的内心深处,因此可能需要一个修复程序。我要试试看。@Josh Knauer:简单地修复你的应用程序要比在一条表明你的应用程序不遵循HTTP规则的普通消息中尝试沉默要容易得多。我同意。事实上,应用程序中的行为已经被修复。我对深入研究活塞的兴趣可能更大,因此对我来说,了解更多关于图书馆的知识,而不是我认为这是一般情况下最好的想法:)我想在这个问题的背景下,尽管最好把答案留在“这很正常,别管它了。”但如果图像没有上传怎么办?我也有这个问题,它在本地工作,但不在服务器上。