Files
dsh_ai1net_server/归档/poc-dsh-local/patch-25.py
T
admin ce8e6ceed9 chore(工作区): 纳入版本控制基线(回收 411 MB 过程产物)
回收 411 MB(470 M → 58.8 M),全部经回收站,可恢复:
- 待清理/(146.2 M,含 relay 分片 128 M 与 42 项过程目录)
- tmp/(32.4 M,按接续棒命名的过程临时区)
- .workbuddy/tmp/(39.5 M)
- 4 份 workbuddy.db 冗余副本(101 M,09-23 事故的坏副本 / 抢救产物)
- tmp/im16/gw/centrifugo 二进制(63.9 M,可重下)+ 缓存残留

入库范围:常驻规则(CODEBUDDY.md / README.md / state.py)、在途接续入口与
接续包、docs/、交付物/、交接单/、归档/、scripts/、.codebuddy/、
.workbuddy/memory/;共 398 件,其中 >60 KB 的 26 件全为文档。

排除(.gitignore):tmp/、待清理/、运行态日志与缓存、*.db 与 DB 备份整目录、
打包二进制(*.tar.gz / *.tgz)、记忆修复前备份。
2026-09-24 07:51:03 +08:00

70 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# 档案 25:not_running 的浏览器导航兜底 —— 绝不吐 JSON;并发进场等待在飞的实例
# 用法: python3 patch-25.py /opt/dshs
import io
import os
import sys
root = sys.argv[1] if len(sys.argv) > 1 else '.'
p = os.path.join(root, 'src/supervisor/proxy.ts')
s = io.open(p, encoding='utf-8').read()
old = """ // 实例未运行(后台回收/崩溃/停止后刷新会话页)→ 自动重启并 302 到新实例 URL,
// 透明恢复,不必让用户重新登录。
if (access.code === 404 && access.error === 'not_running' && access.userId !== undefined) {
try {
const folderAbs = app.userFs.resolvePath(access.userId, '')
const instance = await app.supervisor.launch(access.userId, folderAbs, undefined)
const token = instance.launchToken ?? ''
if (token !== '') {
const scheme = app.config.secureCookies ? 'https' : 'http'
reply.redirect(`${scheme}://${clientHost(request.headers)}/?token=${encodeURIComponent(token)}`)
return
}
} catch {
// 启动失败(目录异常/已在启动中等)→ 落到下方 not_running 响应
}
}
reply.code(access.code).send({ error: access.error })
return"""
new = """ // 实例未运行(后台回收/崩溃/停止/熔断后刷新会话页)→ 自动重启并 302 到新实例 URL,
// 透明恢复,不必让用户重新登录。
if (access.code === 404 && access.error === 'not_running' && access.userId !== undefined) {
const navScheme = app.config.secureCookies ? 'https' : 'http'
const navHost = clientHost(request.headers) ?? app.config.baseDomain
const isNavigation =
request.raw.method === 'GET' && (request.headers.accept ?? '').includes('text/html')
let token = ''
try {
const folderAbs = app.userFs.resolvePath(access.userId, '')
const instance = await app.supervisor.launch(access.userId, folderAbs, undefined)
token = instance.launchToken ?? ''
} catch {
// 并发进场(另一个请求正在拉起 → AlreadyRunningError)或启动异常:
// 等一会儿取在飞实例的 token,而不是直接把 404 JSON 甩给浏览器(档案 25)。
try {
await app.supervisor.waitForLaunchTokenForUser(access.userId, 20000)
token = (await app.supervisor.status(access.userId)).main?.launchToken ?? ''
} catch {
token = ''
}
}
if (token !== '') {
reply.redirect(`${navScheme}://${navHost}/?token=${encodeURIComponent(token)}`)
return
}
// 仍拿不到 token:浏览器导航一律回门户(可点「进入」,避免看到裸 JSON);API 保持 JSON。
if (isNavigation) {
reply.redirect(`${navScheme}://${app.config.baseDomain}/`)
return
}
}
reply.code(access.code).send({ error: access.error })
return"""
assert old in s, 'anchor not found'
s = s.replace(old, new, 1)
io.open(p, 'w', encoding='utf-8', newline='').write(s)
print('patched: not_running 浏览器导航兜底 + 并发等待')