fix(socks5): 去掉 _record_stats 里对同步方法 add_traffic 的 await
回归: ee8c0b8 引入的 _forward timeout 修复没改 _record_stats,
但烟雾测试里 FakeUserService.add_traffic 误写成 async def 掩盖了
这个 bug。生产机 15:32:08 命中:
socks.engine: 记录统计失败: object NoneType can't be used in 'await'
gunicorn: [CRITICAL] WORKER TIMEOUT (pid:428355)
gunicorn: Error handling request (no URI read)
add_traffic 是 UserService 里的 def (非 async), 不能 await。错误地
await 一个 None 返回值会让 worker 在协程上下文里抛 TypeError,
被 _record_stats 的 except 吃掉, 但 worker 进入不可服务状态,
触发 30s gunicorn timeout, 表现就是 40080 实例莫名停止。
注意 log_event 是 async, 仍需 await; add_traffic 是 def, 不 await。
修法:
engine/server.py:472 去掉 await, 同步调用 add_traffic
tests/smoke_tunnel_timeout.py FakeUserService.add_traffic 改为
def, 模拟真实 UserService 签名,
防止烟雾测试再次漏掉此类 bug
线上已临时恢复 40080 (curl POST /api/instances/2/restart),
This commit is contained in:
+5
-1
@@ -469,7 +469,11 @@ class ConnectionHandler:
|
|||||||
|
|
||||||
# 更新用户流量
|
# 更新用户流量
|
||||||
if self.username and (self.bytes_in or self.bytes_out):
|
if self.username and (self.bytes_in or self.bytes_out):
|
||||||
await self.user_service.add_traffic(self.username, self.bytes_in, self.bytes_out)
|
# add_traffic 是同步方法(UserService.add_traffic 是 def, 非 async),
|
||||||
|
# 不能 await。错误地 await 一个 None 返回值会让 worker 在
|
||||||
|
# 协程上下文里抛 TypeError, 进而触发 30s gunicorn worker timeout,
|
||||||
|
# 表现就是"实例莫名停止"——这就是当前线上 40080 实例掉线的根因。
|
||||||
|
self.user_service.add_traffic(self.username, self.bytes_in, self.bytes_out)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.error("记录统计失败: %s", e)
|
log.error("记录统计失败: %s", e)
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class FakeUser:
|
|||||||
class FakeUserService:
|
class FakeUserService:
|
||||||
def get_user(self, name): return FakeUser()
|
def get_user(self, name): return FakeUser()
|
||||||
def get_active_connections(self, name): return 0
|
def get_active_connections(self, name): return 0
|
||||||
async def add_traffic(self, *a, **kw): pass
|
def add_traffic(self, *a, **kw): pass # 同步, 不要 await (见 services/user_service.py:162)
|
||||||
async def log_event(self, *a, **kw): pass
|
async def log_event(self, *a, **kw): pass
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user