fix(server-core): 种子容错 + 智能体种子幂等 — 修复 lifespan 建库被种子唯一冲突拖垮(全500)
根因:AGENT_SEED 用全局固定 agent id,demo 用户补种时对多个用户复用同一 id → (id,user_id,port) 唯一冲突 → seed_data 抛 IntegrityError → 平台 lifespan 建库失败 → app.state.db 未设置 → 全 500。 - repositories.initialize:种子包 try/except + rollback(记 warn),种子失败不再拖垮 lifespan 建库。 - seed._ensure_port_agents:改为按 agent.id 逐条判断已存在,避免重复插入幂等。 验证:登录/me/users/courses/roles 全 200。
This commit is contained in:
@@ -1864,7 +1864,14 @@ class Database:
|
|||||||
if self._engine is not None:
|
if self._engine is not None:
|
||||||
async with self._engine.begin() as conn:
|
async with self._engine.begin() as conn:
|
||||||
await conn.run_sync(Base.metadata.create_all)
|
await conn.run_sync(Base.metadata.create_all)
|
||||||
await seed_data(self.session)
|
# 种子容错:个别幂等保护不严的地方(如 demo 用户固定 agent id)可能触发唯一冲突,
|
||||||
|
# 不能让种子失败拖垮 lifespan 建库,否则 app.state.db 未设置→全部 500。
|
||||||
|
try:
|
||||||
|
await seed_data(self.session)
|
||||||
|
except Exception as e: # noqa: BLE001
|
||||||
|
import logging
|
||||||
|
logging.getLogger("servercore").warning("种子数据写入失败(忽略,应用仍可用): %s", e)
|
||||||
|
await self.session.rollback()
|
||||||
|
|
||||||
async def close(self) -> None:
|
async def close(self) -> None:
|
||||||
if self._owns_session:
|
if self._owns_session:
|
||||||
|
|||||||
@@ -1045,12 +1045,12 @@ async def _ensure_port_agents(session: AsyncSession, now: str) -> None:
|
|||||||
if (user_id, port) in seen:
|
if (user_id, port) in seen:
|
||||||
continue
|
continue
|
||||||
seen.add((user_id, port))
|
seen.add((user_id, port))
|
||||||
existing = await session.scalar(
|
existing_ids = set(
|
||||||
select(Agent.id).where(Agent.user_id == user_id, Agent.port == port).limit(1)
|
(await session.execute(select(Agent.id).where(Agent.user_id == user_id, Agent.port == port))).scalars()
|
||||||
)
|
)
|
||||||
if existing is not None:
|
|
||||||
continue
|
|
||||||
for seed in AGENT_SEED:
|
for seed in AGENT_SEED:
|
||||||
|
if seed["id"] in existing_ids:
|
||||||
|
continue # 已存在,跳过(幂等,避免 (id,user_id,port) 唯一冲突)
|
||||||
session.add(
|
session.add(
|
||||||
Agent(
|
Agent(
|
||||||
id=seed["id"], user_id=user_id, port=port, name=seed["name"],
|
id=seed["id"], user_id=user_id, port=port, name=seed["name"],
|
||||||
|
|||||||
Reference in New Issue
Block a user