合入 nr8/b 之后的配合:启动时先等库再做版本检查(cluster/version.preflight 是第一次连库,放在等库之前的话库的容器晚一步起来服务就直接崩),单测核对先后;deploy/README 多进程一段写明内置 PostgreSQL 是直连、不用 AGENTLAB_DATABASE_DIRECT_URL,upgrade 先停掉旧容器(全部工作进程)、备份、再起新版本,正合不许新旧版本同时运行的拦截

This commit is contained in:
ThearchyHelios
2026-10-19 14:06:20 +08:00
parent 5318c33f57
commit 322ba5969b
3 changed files with 32 additions and 1 deletions
+3 -1
View File
@@ -59,9 +59,11 @@ async def lifespan(_: FastAPI) -> AsyncIterator[None]:
# (app/cluster/guard.py)。PostgreSQL 可以多进程,什么都不做
guard.acquire()
# PgBouncer 事务模式(AGENTLAB_DB_PGBOUNCER=1)要另给直连地址,没给就拒绝启动(db/base.check_pgbouncer)
from app.db.base import check_pgbouncer
from app.db.base import check_pgbouncer, wait_for_database
check_pgbouncer()
# 库还没起来(和 PostgreSQL 容器一起起、库还在初始化)时先按退避等它:下面的版本检查就要连库,不等的话一上来就崩
await wait_for_database()
# 不许新旧版本混跑(app/cluster/version.py):库里还有活着的、版本不同的进程就不启动——在补列之前看
from app.cluster import version
+24
View File
@@ -135,3 +135,27 @@ async def test_a_missing_database_on_a_real_server_is_raised_at_once():
await engine.dispose()
assert clock.slept == [], caught.value
assert "agentlab_no_such_database" in str(caught.value)
async def test_startup_waits_for_the_database_before_the_version_check(monkeypatch):
"""lifespan 里第一次连库的是版本检查(cluster/version.preflight):等库要在它前面,库的容器晚一步起来时服务不至于直接崩。"""
from app.cluster import guard, version
from app.db import base
from app.main import app, lifespan
calls: list[str] = []
async def waited(*_a, **_k) -> None:
calls.append("wait")
async def checked(*_a, **_k) -> None:
calls.append("preflight")
raise RuntimeError("到这里就够了")
monkeypatch.setattr(guard, "acquire", lambda: None)
monkeypatch.setattr(base, "wait_for_database", waited)
monkeypatch.setattr(version, "preflight", checked)
with pytest.raises(RuntimeError, match="到这里就够了"):
async with lifespan(app):
pass
assert calls == ["wait", "preflight"]
+5
View File
@@ -241,6 +241,11 @@ docker run --rm --user 10001:10001 -v "$(pwd)/data:/data" --env-file agentlab.en
问数据和后台任务(规矩见仓库 README「多进程」)。SQLite 时设大于 1 会启动失败(照实报错:SQLite 只支持单进程)。
几台机器、几个容器指着同一个库也行,但数据目录要放在共享存储上、每台挂在同一个路径,限制见仓库 README「多进程」。
内置 PostgreSQL 是直连(中间没有 PgBouncer),多进程时什么都不用另设(不用 `AGENTLAB_DATABASE_DIRECT_URL`)。新旧版本的进程不能同时
连着一个库(代码里拦着:新版本发现库里还有活着的旧版本进程就拒绝启动)。`./deploy.sh upgrade` 就是按这个顺序做的:先停掉旧容器
(里面的全部工作进程一起停)、备份,再起新版本;旧进程要是被强杀、登记还没过期,新版本启动时会等它过期(最多半分钟左右)。
同一个库还接着别处的 AgentLab 进程(另一台机器、另一个容器)的,升级前先把它们也停掉。
## 升级
把新版本的离线包拷到机器上,解到一个新目录,然后: