从run 中移除了全局try-except块,增强了eventlet内部错误处理
This commit is contained in:
@@ -11,18 +11,54 @@ eventlet.monkey_patch()
|
|||||||
# 配置 eventlet hub 以更优雅地处理 IOClosed 错误
|
# 配置 eventlet hub 以更优雅地处理 IOClosed 错误
|
||||||
try:
|
try:
|
||||||
from eventlet.hubs import hub
|
from eventlet.hubs import hub
|
||||||
|
from eventlet import hubs
|
||||||
|
|
||||||
# 保存原始的 handle_error 方法
|
# 保存原始的 handle_error 方法
|
||||||
original_handle_error = hub.Hub.handle_error
|
original_handle_error = hub.Hub.handle_error
|
||||||
|
original_switch = hubs.hub.Hub.switch
|
||||||
|
|
||||||
def custom_handle_error(self, context, type, value, tb):
|
def custom_handle_error(self, context, type, value, tb):
|
||||||
# 忽略 IOClosed 错误
|
# 忽略 IOClosed 错误和相关的 EOFError
|
||||||
if type.__name__ == 'IOClosed' and 'Operation on closed file' in str(value):
|
error_str = str(value)
|
||||||
|
if (type.__name__ == 'IOClosed' and 'Operation on closed file' in error_str) or \
|
||||||
|
(type.__name__ == 'EOFError') or \
|
||||||
|
(type.__name__ == 'OSError' and 'Bad file descriptor' in error_str):
|
||||||
return
|
return
|
||||||
# 其他错误调用原始方法
|
# 其他错误调用原始方法
|
||||||
original_handle_error(self, context, type, value, tb)
|
original_handle_error(self, context, type, value, tb)
|
||||||
|
|
||||||
|
def custom_switch(self):
|
||||||
|
try:
|
||||||
|
return original_switch(self)
|
||||||
|
except Exception as e:
|
||||||
|
# 捕获 switch 方法中可能出现的 IOClosed 错误
|
||||||
|
error_str = str(e)
|
||||||
|
if (type(e).__name__ == 'IOClosed' and 'Operation on closed file' in error_str) or \
|
||||||
|
(type(e).__name__ == 'EOFError') or \
|
||||||
|
(type(e).__name__ == 'OSError' and 'Bad file descriptor' in error_str):
|
||||||
|
# 优雅处理,返回继续运行
|
||||||
|
return None
|
||||||
|
# 其他异常重新抛出
|
||||||
|
raise
|
||||||
|
|
||||||
# 替换原始方法
|
# 替换原始方法
|
||||||
hub.Hub.handle_error = custom_handle_error
|
hub.Hub.handle_error = custom_handle_error
|
||||||
|
hubs.hub.Hub.switch = custom_switch
|
||||||
|
|
||||||
|
# 同样处理 greenio 模块的错误
|
||||||
|
from eventlet import greenio
|
||||||
|
original_recv_loop = greenio.base.GreenSocket._recv_loop
|
||||||
|
|
||||||
|
def custom_recv_loop(self, recv_func, recv_args, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
return original_recv_loop(self, recv_func, recv_args, *args, **kwargs)
|
||||||
|
except (hubs.IOClosed, EOFError, OSError) as e:
|
||||||
|
# 优雅处理 IO 错误
|
||||||
|
if hasattr(e, 'errno') and e.errno in (9, 107): # Bad file descriptor or Operation on closed file
|
||||||
|
return b''
|
||||||
|
raise
|
||||||
|
|
||||||
|
greenio.base.GreenSocket._recv_loop = custom_recv_loop
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# 如果修改失败,忽略错误
|
# 如果修改失败,忽略错误
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -10,23 +10,11 @@ logging.getLogger('werkzeug').setLevel(logging.ERROR)
|
|||||||
app = create_app()
|
app = create_app()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
socketio.run(
|
||||||
socketio.run(
|
app,
|
||||||
app,
|
host="0.0.0.0",
|
||||||
host="0.0.0.0",
|
port=5200,
|
||||||
port=5200,
|
debug=False, # 开发期打开
|
||||||
debug=False, # 开发期打开
|
allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示
|
||||||
allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示
|
log_output=False # 禁用详细输出
|
||||||
log_output=False # 禁用详细输出
|
)
|
||||||
)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Server stopped by user")
|
|
||||||
except Exception as e:
|
|
||||||
# 捕获所有异常,包括 eventlet 内部的 IOClosed 错误
|
|
||||||
if "IOClosed" in str(type(e).__name__) or "Operation on closed file" in str(e):
|
|
||||||
# 优雅处理 eventlet 关闭文件的错误
|
|
||||||
print("Eventlet IOClosed error handled gracefully")
|
|
||||||
else:
|
|
||||||
# 其他异常仍然打印
|
|
||||||
import traceback
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|||||||
Reference in New Issue
Block a user