- 新增 SQLite:measure/health 快照、delivery_cursor 单消费者 pop;clear/start_fresh 可清空库 - biomass GET 仅返回约定 data 字段,X-Fish-Biomass-New 表示是否有新快照;poller 读响应头 - loguru 桥接 uvicorn,子进程 stdout 流式输出;format_json_pretty 与算法摘要日志 - measure/action watch 无新任务时限流 WARNING;watch_idle 共用逻辑 - 依赖 loguru;新增 db、logging_config、subprocess_run、watch_idle、启动脚本 FishMeasure: 更新 fish_video_weight_evaluation 与 predict_weigth_from_svo2;移除未用 refbox/segmentation 脚本 Made-with: Cursor
57 lines
1.5 KiB
Python
57 lines
1.5 KiB
Python
"""后台 watch 无新任务时的限流 warning(FishMeasure / FishAction 共用)。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import os
|
||
import time
|
||
from pathlib import Path
|
||
|
||
from loguru import logger
|
||
|
||
|
||
def idle_warn_interval_sec(override_env: str) -> float:
|
||
"""优先读 override_env,否则 FISH_WATCH_IDLE_WARN_INTERVAL_SEC,默认 120。"""
|
||
v = os.environ.get(override_env)
|
||
if v is not None and str(v).strip() != "":
|
||
return float(v)
|
||
return float(os.environ.get("FISH_WATCH_IDLE_WARN_INTERVAL_SEC", "120"))
|
||
|
||
|
||
class IdleWatchWarnState:
|
||
"""记录上次告警时间;有推理成功时重置计时。"""
|
||
|
||
__slots__ = ("_last_mono",)
|
||
|
||
def __init__(self) -> None:
|
||
self._last_mono = time.monotonic()
|
||
|
||
def on_did_work(self) -> None:
|
||
self._last_mono = time.monotonic()
|
||
|
||
|
||
def maybe_warn_idle_watch(
|
||
*,
|
||
did_work: bool,
|
||
log_tag: str,
|
||
algo_name: str,
|
||
idle_hint: str,
|
||
watch_dir: Path,
|
||
state: IdleWatchWarnState,
|
||
interval_sec: float,
|
||
) -> None:
|
||
"""本轮未跑推理时按 interval 限流打 warning;interval<=0 则每轮无任务都打。"""
|
||
if did_work:
|
||
state.on_did_work()
|
||
return
|
||
now = time.monotonic()
|
||
if interval_sec > 0 and now - state._last_mono < interval_sec:
|
||
return
|
||
state._last_mono = now
|
||
logger.warning(
|
||
"[{}] 本轮无新数据可供 {} 处理({}) | dir={}",
|
||
log_tag,
|
||
algo_name,
|
||
idle_hint,
|
||
watch_dir,
|
||
)
|