4

我有一个 iPhone 应用程序,它使用 Python 中实现的 Web 服务,使用 Django 和 Piston,通过 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

出现在我的服务器的错误日志中。

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

4

2 回答 2

7

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

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

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

  • 诸如“客户端读取'状态:304',然后关闭连接”或“客户端读取所有字节,然后关闭连接,即使它已经请求连接应该被重用”这样的情况是适合不发出任何类型的情况除了log.debug()通话之外的日志记录。

  • 但是像“客户端在文件中间停止读取,因为当 ISP 路由器发生中风时连接中断”这样的情况值得记录错误。有些事情没有成功完成,您的服务器应用程序构建的任何事务状态都应该回滚。在这种情况下,IOError向上传播是正确的做法。

只有在可以引发它们的每个地方,修改代码以区分这两种情况时,此类错误才会被静音。在那之前,wsgi 的作者似乎都在谨慎行事。因此,据我所知,没有快速解决此问题的方法。


(另外,我应该注意这不是 django 特有的,我使用 paste+pylons 并且发生了同样的事情)

于 2011-09-06T16:40:16.447 回答
1

看到这个:http ://code.google.com/p/modwsgi/issues/detail?id=29

如果处理可迭代,则消息记录调试级别并且不使用 Python 异常。因此要在使用可迭代时查看客户端关闭连接问题,则需要调试 LogLevel。

显然,您需要将 Django 响应调整为可迭代而不是字符串。

于 2011-09-06T17:39:10.853 回答