fix(#89+#90防线): 组合回测选实例不再预填标的池+vps-deploy僵尸API端口守卫——#89:prefillFromInstance删symbol_or_pool→form.pool预填(#86a定稿实例不选标的,老实例存的all不该悄悄改用户池选择;策略/max_pool/benchmark参数预填保留);#90防复发:API重启步在/end后netstat查8000持有PID强杀+端口未释放硬fail(2026-08-16实录uvicorn reload孤儿子进程17836跨两轮部署占端口,新实例静默抢不到,旧代码继续serve→500旧bug重现,人工taskkill+重拉后同请求200+task_id实证);build绿+yaml解析过 [nas]
This commit is contained in:
@@ -66,12 +66,21 @@ jobs:
|
||||
set -e
|
||||
ssh 49.232.102.198 'C:\Python310\python.exe -X utf8 C:\sanguo_vnpy_v2\scripts\nas_sync\vps_update_dist.py' | tee /tmp/dist_swap.log
|
||||
grep -q DIST_UPDATE_DONE /tmp/dist_swap.log
|
||||
# 停 API → 等端口彻底释放(旧实例被杀后端口有滞留, 立即重启会 10048 静默崩)
|
||||
# 停 API → 僵尸端口守卫 → 等端口彻底释放(否则 fail) → 重启
|
||||
# 2026-08-16 实录: /end 杀不掉 uvicorn reload 孤儿子进程, 旧进程跨两轮
|
||||
# 部署占 8000, 新实例静默抢不到端口, /docs 200 验的还是旧代码 → 500 旧 bug 重现
|
||||
ssh 49.232.102.198 'schtasks /end /tn sanguo-api' || true
|
||||
ZPID=$(ssh 49.232.102.198 'netstat -ano -p tcp' | tr -d '\r' | grep ':8000' | grep -i LISTENING | awk '{print $NF}' | sort -u | head -1)
|
||||
if [ -n "$ZPID" ]; then
|
||||
echo "僵尸 API 进程 PID=$ZPID 仍占 8000, 强杀"
|
||||
ssh 49.232.102.198 "taskkill /F /T /PID $ZPID" || true
|
||||
fi
|
||||
PORT_FREED=0
|
||||
for i in $(seq 1 30); do
|
||||
ssh 49.232.102.198 'netstat -ano -p tcp' | tr -d '\r' | grep -q ':8000.*LISTEN' || { echo "port freed after $((i*2))s"; break; }
|
||||
ssh 49.232.102.198 'netstat -ano -p tcp' | tr -d '\r' | grep -q ':8000.*LISTEN' || { echo "port freed after $((i*2))s"; PORT_FREED=1; break; }
|
||||
sleep 2
|
||||
done
|
||||
if [ "$PORT_FREED" != "1" ]; then echo "❌ 端口 8000 未释放, 强杀后重启会 10048, 终止"; exit 1; fi
|
||||
ssh 49.232.102.198 'schtasks /run /tn sanguo-api'
|
||||
# 等新实例监听 + /docs 可用(VPS 启动需数分钟, 上限 10 分钟)
|
||||
for i in $(seq 1 60); do
|
||||
|
||||
@@ -436,7 +436,8 @@ async function prefillFromInstance(instId: number): Promise<void> {
|
||||
const p = inst.params || {}
|
||||
if (typeof p.max_pool === 'number') form.max_pool = p.max_pool
|
||||
if (typeof p.benchmark === 'string') form.benchmark = p.benchmark
|
||||
if (inst.symbol_or_pool && inst.symbol_or_pool !== '') form.pool = inst.symbol_or_pool
|
||||
// #89 标的池不预填:#86a 定稿「实例不选标的,发起时定」——老实例存的
|
||||
// symbol_or_pool(all 等)不该悄悄改用户的池选择
|
||||
} catch {
|
||||
/* 预填失败走默认 */
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user