如何捕获“[Errno 32]断管”在WSGI处理程序中

编程入门 行业动态 更新时间:2024-10-10 10:25:21
本文介绍了如何捕获“[Errno 32]断管”在WSGI处理程序中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

WSGI对于构建高度并发的HTTP服务器非常有用,可以支持例如但是,长轮询通常会在某些时候由客户端结束长时间运行的HTTP请求;要清理任何资源和打开句柄,应该通知WSGI服务器后端任何此类事件,但是,目前似乎无法在WSGI处理程序中捕获这些事件:

WSGI is extremely useful for building highly concurrent HTTP servers to support e.g. long polling, however, typically, the long running HTTP request will at some point be ended by the client side; to clean up any resources and open handles, the WSGI server backend should be notified of any such events, however, it doesn't currently seem to be possible to catch those events in the WSGI handler:

# pseudocode example def application(env, start_response): start_response(...) q = Queue() ev_handle = register_event_handler(lambda event, arg: q.put((event, arg))) # ??? need to call e.g. ev_handle.unregister() when the HTTP request is terminated return iter(lambda: render(q.get()), None)

例如,当使用 gevent.pywsgi 时,相应的异常(错误:[Errno] 32]破坏的管道)在gevent中的某处被抛出,甚至似乎都没有出现在处理程序可能看到它的任何地方:

For example, when using gevent.pywsgi, the corresponding exception (error: [Errno 32] Broken pipe) is thrown somewhere inside gevent and never even seems to surface anywhere the handler could potentially see it:

Traceback (most recent call last): File "/Users/erik.allik/.virtualenvs/myproj/lib/python2.7/site-packages/gevent/pywsgi.py", line 508, in handle_one_response self.run_application() File "/Users/erik.allik/.virtualenvs/myproj/lib/python2.7/site-packages/gevent/pywsgi.py", line 495, in run_application self.process_result() File "/Users/erik.allik/.virtualenvs/myproj/lib/python2.7/site-packages/gevent/pywsgi.py", line 486, in process_result self.write(data) File "/Users/erik.allik/.virtualenvs/myproj/lib/python2.7/site-packages/gevent/pywsgi.py", line 376, in write self._write(data) File "/Users/erik.allik/.virtualenvs/myproj/lib/python2.7/site-packages/gevent/pywsgi.py", line 369, in _write self._sendall(data) File "/Users/erik.allik/.virtualenvs/myproj/lib/python2.7/site-packages/gevent/pywsgi.py", line 355, in _sendall self.socket.sendall(data) File "/Users/erik.allik/.virtualenvs/myproj/lib/python2.7/site-packages/gevent/socket.py", line 458, in sendall data_sent += self.send(_get_memory(data, data_sent), flags) File "/Users/erik.allik/.virtualenvs/myproj/lib/python2.7/site-packages/gevent/socket.py", line 435, in send return sock.send(data, flags)

推荐答案

看起来当请求被终止时会发生什么,除了(看似无法捕获的)异常回溯之外,从WSGI处理程序返回的迭代器是 .close() -d。因此可以确定何时应关闭与响应相关联的任何工人/资源/句柄。这基本上是 werkzeug.wsgi.ClosingIterator 所做的:

Looks like what happens when a request gets terminated is that, in addition to the (seemingly uncatchable) exception traceback, the iterator that was returned from the WSGI handler is .close()-d. It is thus possible to determine when the any workers/resources/handles associated with the response should be closed. This is basically what werkzeug.wsgi.ClosingIterator does:

class ClosingIterator(object): def __init__(self, iterable, on_close): iterator = iter(iterable) self.close = on_close def __iter__(self): return self def __next__(self): return self._next() def application(env, start_response): start_response(...) q = Queue() ev_handle = register_event_handler(lambda event, arg: q.put((event, arg))) return ClosingIterator( iter(lambda: render(q.get()), None), on_close=ev_handle.unregister )

但是这不会使错误消息/回溯无声,但这似乎是可以忍受的除非有人能提出解决方案,甚至可以解决这个问题。

This does not however silence the error message/traceback, but this seems tolerable unless somebody can come up with a solution that can fix even that.

更多推荐

如何捕获“[Errno 32]断管”在WSGI处理程序中

本文发布于:2023-11-24 14:01:10,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1625503.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:程序   Errno   WSGI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!