- 排行榜页顶部新增「实时并发监控」面板(admin-only):当前并发大模型调用数 +
调用列表(用户/智能体/类型/已运行时长),每行「停止」+「全部停止」经
RunManager.cancel 真正中断 LLM 流式调用,减轻大模型压力
- 并发量折线图(峰值/均值,按分钟/小时):新增轻量后台采样器写入新表
concurrency_samples(create_all 自动建表),可按分/时聚合
- 大模型出字速度折线图(tokens/秒,按分钟/小时):复用 llm_call_metrics 聚合,
便于定位是模型/供应商慢
- 后台采样可开关、默认关闭(opt-in)、运行时切换免重启、对线上零影响
(单条极小 INSERT、保留期清理、查询有上限、全程 best-effort)
- 409 中文化:上一轮未结束又发新问题时返回中文提示,前端 onError 友好映射
后端:runtime/runs/manager.py(list_active)、persistence/concurrency(新模块)、
config/system_settings(ConcurrencyMonitorSettings)、gateway/routers/admin_active_runs、
app.py(采样后台任务)、services.py(409)。前端:core/admin/{active-runs,hooks}、
components/workspace/admin/concurrency-monitor、AdminUserLeaderboardPage、threads/hooks。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
32 lines
1.2 KiB
Python
32 lines
1.2 KiB
Python
"""ORM model for periodic concurrency (system-pressure) samples.
|
|
|
|
A background sampler writes one row every few seconds holding the number of
|
|
in-flight model runs at that instant. The admin monitor aggregates these into
|
|
per-minute / per-hour buckets to draw the 并发量 pressure line chart, even for
|
|
time windows before the admin opened the page.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from datetime import UTC, datetime
|
|
|
|
from sqlalchemy import Integer
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from deerflow.persistence.base import Base
|
|
from deerflow.persistence.types import BeijingDateTime
|
|
|
|
|
|
class ConcurrencySampleRow(Base):
|
|
"""One sampled snapshot of concurrent in-flight model runs."""
|
|
|
|
__tablename__ = "concurrency_samples"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
# Wall-clock time the sample was taken (Beijing time on disk, tz-aware in Python).
|
|
sampled_at: Mapped[datetime] = mapped_column(
|
|
BeijingDateTime(), index=True, default=lambda: datetime.now(UTC)
|
|
)
|
|
# Number of runs whose status was pending/running at ``sampled_at``.
|
|
active_count: Mapped[int] = mapped_column(Integer, default=0)
|