Как предотвратить «IOError: не удалось записать данные», когда клиент закрывает соединение с приложением Django / WSGI? - PullRequest
4 голосов
/ 06 сентября 2011

У меня есть приложение для iPhone, использующее веб-сервисы, реализованные на Python, использующие Django и Piston, работающие на сервере apache через WSGI.

Иногда приложение закрывает соединение с сервером до завершения вызова,Когда он делает это, он вызывает:

[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

в журналах ошибок моего сервера.

Я могу «исправить» проблему в приложении, не явно закрывая соединение, а простооставив его для завершения загрузки и игнорируя результат.Тем не менее, я хотел бы исправить это на стороне сервера, если это возможно.Как я могу это сделать?

Ответы [ 2 ]

6 голосов
/ 06 сентября 2011

[заявление об отказе: это объяснение «почему это нелегко сделать», а не решение]

Как заметил @Slott, это определенно технически правильное поведение, когда stream.close или stream.write вызывается в закрытом сокете. Однако я понимаю мотивацию вопроса ... в контексте приложения wsgi клиенты, разрывающие соединение после полного или частичного чтения, не являются «исключительным» поведением, это происходит постоянно. Для того, чтобы его оставить необработанным, создается впечатление, что оно было неожиданным / код не был подготовлен для этого, хотя на самом деле это ожидаемо и не должно быть достойным внимания. Так что было бы неплохо исправить.

Сложность в том, что вам нужно найти способ различать дела ...

  • Ситуации, такие как "клиент прочитал 'Статус: 304', а затем закрыл соединение" или "клиент прочитал все байты, а затем закрыл соединение, даже если он запросил соединение, должно быть повторно использовано", это ситуации, где это будет целесообразно не выдавать никаких журналов, кроме вызова log.debug().

  • Но такие ситуации, как «клиент прекратил чтение в середине файла, потому что соединение оборвалось, когда у маршрутизатора ISP произошел удар», достойны регистрации ошибки. Что-то не удалось успешно завершить, и любое состояние транзакции, созданное вашим серверным приложением, следует откатить. В этом случае IOError распространяется вверх - это правильно.

Такие ошибки можно заставить замолчать только в том случае, если в каждом месте, где они могут возникнуть, код будет изменен для различения этих двух случаев. До этого авторы wsgi, по-видимому, ошибались из-за осторожности. Так что я не знаю, как быстро это исправить.


(Кроме того, я должен отметить, что это не специфично для django, я использую paste + pylons и происходит то же самое)

1 голос
/ 06 сентября 2011

Смотрите это: http://code.google.com/p/modwsgi/issues/detail?id=29

Если обработка повторяется, то сообщение регистрируется на уровне отладки, и нет Используется исключение Python. Таким образом, чтобы увидеть проблемы закрытого подключения клиента если используется итерация, тогда для отладки нужен LogLevel.

Очевидно, вам нужно настроить ответ Django, чтобы он был итеративным, а не строкой.

...