fix(socks5): 加后台 sync loop, 周期探活自动救活死 SOCKS5 实例
背景:
is_alive() 健康探活已就绪, 但 sync_instances 只能由 API 手动触发。
没人调 API 就没人探活, 死掉的 SOCKS5 实例一直挂着, DB.running 还是
true, 用户看到的就是'实例莫名停止'。这是最后一块拼图。
变更:
app.py
+ _start_sync_loop() 后台 daemon 线程, 周期调用 sync_instances
(默认 30s, SM_SYNC_INTERVAL 可调, SM_SYNC_LOOP_ENABLE
可关)。线程级单例, 多次 create_app 只启一次。
+ create_app 末尾调 _start_sync_loop + 初始 sync_instances, 保证
gunicorn worker 启动时就把实例拉起来
engine/instances.py
M is_alive() docstring 补充判定依据 (thread/server/is_serving)
测试:
+ tests/e2e_sync_loop.py create_app 启动 loop -> 插 DB 实例 -> loop 拉起
-> kill server socket -> loop 自动救活 + 换对象
本地 3 次连续运行全 PASS, 端口 ~4.5s 被救活
验证:
- smoke tunnel timeout: PASS
- e2e lifecycle (userpass + add_traffic): PASS
- e2e health check (sync_instances 探活): PASS
- e2e sync loop (后台自动救活): PASS
- app import: OK
This commit is contained in:
+6
-1
@@ -159,6 +159,12 @@ class Socks5Server:
|
||||
True 但 server 实际不再 accept。
|
||||
|
||||
调用方应据此重启实例, 否则 DB 里 running=true 是谎言。
|
||||
|
||||
判定:
|
||||
- thread 死了 -> 死 (无法恢复)
|
||||
- server is None -> 死 (还没起来)
|
||||
- server is_serving() == False -> 死 (socket 已关, asyncio.Server
|
||||
不能复用同一个对象重新 serve, 必须新 Socks5Server)
|
||||
"""
|
||||
if not self.running:
|
||||
return False
|
||||
@@ -166,7 +172,6 @@ class Socks5Server:
|
||||
return False
|
||||
if self.server is None:
|
||||
return False
|
||||
# server.is_serving() 反映 socket 是否在 listen, 比检查 fd 状态靠谱
|
||||
if not self.server.is_serving():
|
||||
return False
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user