如何防止“IOError:写入数据失败”当客户端关闭与 Django/WSGI 应用程序的连接时?

发布于 2024-12-03 08:22:41 字数 486 浏览 2 评论 0原文

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

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

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

I have an iPhone app that is using web services implemented in Python, using Django and Piston, running on an apache server through WSGI.

Sometimes the app closes its connection to the server before a call is finished. When it does this it causes a:

[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

to appear in my server's error logs.

I can "fix" the problem in the app by not explicitly closing the connection, but just leaving it to finish downloading and ignoring the result. However, I'd like fix this on the server-side if possible. How can I do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

狼性发作 2024-12-10 08:22:41

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

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

问题是你必须找到一种方法来区分情况...

  • 诸如“客户端读取'状态:304',然后关闭连接”或“客户端读取所有字节,然后关闭连接,甚至尽管它已请求连接应重用”,但除了 log.debug() 调用之外,不发出任何类型的日志记录是合适的。

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

仅当在每个可能引发此类错误的地方修改代码以区分这两种情况时,此类错误才会被消除。在那之前,wsgi 作者似乎过于谨慎。因此,据我所知,没有快速解决此问题的方法。


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

[disclaimer: this is a "why it can't be easily done" explanation, not a solution]

As @Slott pointed out, this is definitely the technically correct behavior when stream.close or stream.write is called on a closed socket. However, I understand the motivation for the question... in the context of a wsgi app, clients terminating the connection after a full or partial read is not an "exceptional" behavior, it happens all the time. For it to be left unhandled leaves the impression it was unexpected / the code was unprepared for this, when in fact it's expected, and shouldn't be worthy of note. So it'd be nice to fix.

The catch is that you'd have to find a way to distinguish cases...

  • Situations like "client read 'Status: 304', and then closed connection" or "client read all bytes, and then closed connection, even though it had requested connection should be reused" are ones where it would be appropriate to not issue any sort of logging besides a log.debug() call.

  • But situations like "client stopped reading in the middle of file because connection died when an ISP router had a stroke" are worthy of an error being logged. Something didn't successfully complete, and any transactional state your server app builtup should be rolled back. In which case IOError propagating upwards is the right thing to do.

Such errors are only silenceable if at every place they could be raised, the code is modified to distinguish those two cases. Until then, the wsgi authors seem to have erred on the side of caution. So there isn't a quick fix for this that I know of.


(Also, I should note this isn't django-specific, I use paste+pylons and have the same thing happen)

や莫失莫忘 2024-12-10 08:22:41

请参阅:http://code.google.com/p/modwsgi/问题/详细信息?id=29

如果处理可迭代,则消息记录了调试级别,并且没有
使用Python异常。由此看到客户端关闭连接的问题
当使用iterable时,则需要LogLevel进行调试。

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

See this: http://code.google.com/p/modwsgi/issues/detail?id=29

If processing iterable, then message logged a debug level and no
Python exception used. Thus to see client closed connection problems
when iterable used, then need LogLevel to be debug.

Apparently, you would need to tweak your Django response to be an iterable instead of a string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文