修复心跳刷入rollback误用 + API参数规范化

- heartbeat_flush: 移除循环内session.rollback(),防止一个服务器
  刷入失败导致整个批次session状态损坏
- assets.py: 为Query参数添加Query()类型+描述+校验约束,
  统一FastAPI参数风格 (server_id/session_id/limit/parent_id)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-05-22 11:58:15 +08:00
parent cb5b4c42de
commit 0bcfeaa6d6
2 changed files with 10 additions and 8 deletions
+7 -7
View File
@@ -3,7 +3,7 @@ All operations require JWT authentication.
"""
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Request
from fastapi import APIRouter, Depends, HTTPException, Query
from server.api.dependencies import get_db
from server.api.auth_jwt import get_current_admin
@@ -119,7 +119,7 @@ async def delete_platform(
@router.get("/nodes", response_model=list)
async def list_nodes(
parent_id: Optional[int] = None,
parent_id: Optional[int] = Query(None, description="Filter by parent node ID"),
admin: Admin = Depends(get_current_admin),
db: AsyncSession = Depends(get_db),
):
@@ -218,8 +218,8 @@ async def delete_node(
@router.get("/ssh-sessions", response_model=list)
async def list_ssh_sessions(
server_id: Optional[int] = None,
limit: int = 50,
server_id: Optional[int] = Query(None, description="Filter by server ID"),
limit: int = Query(50, ge=1, le=200),
admin: Admin = Depends(get_current_admin),
db: AsyncSession = Depends(get_db),
):
@@ -238,9 +238,9 @@ async def list_ssh_sessions(
@router.get("/command-logs", response_model=list)
async def list_command_logs(
server_id: Optional[int] = None,
session_id: Optional[str] = None,
limit: int = 200,
server_id: Optional[int] = Query(None, description="Filter by server ID"),
session_id: Optional[str] = Query(None, description="Filter by SSH session ID"),
limit: int = Query(200, ge=1, le=500),
admin: Admin = Depends(get_current_admin),
db: AsyncSession = Depends(get_db),
):
+3 -1
View File
@@ -91,7 +91,9 @@ async def heartbeat_flush_loop():
flushed += 1
except Exception as e:
logger.warning(f"Failed to flush server {key}: {e}")
await session.rollback()
# Don't rollback here — just skip this server and continue.
# A partial UPDATE on a single server won't corrupt others.
# The final commit() will persist all successful updates.
await session.commit()
logger.info(f"Heartbeat flush: {flushed}/{len(keys)} servers updated to MySQL")