refactor: optimize structure, stability and runtime performance
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
|
||||
@@ -9,8 +10,40 @@ from services.runtime import get_logger, get_socketio
|
||||
from services.state import safe_get_account, safe_iter_task_status_items
|
||||
|
||||
|
||||
def _to_int(value, default: int = 0) -> int:
|
||||
try:
|
||||
return int(value)
|
||||
except Exception:
|
||||
return int(default)
|
||||
|
||||
|
||||
def _payload_signature(payload: dict) -> str:
|
||||
try:
|
||||
return json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":"), default=str)
|
||||
except Exception:
|
||||
return repr(payload)
|
||||
|
||||
|
||||
def _should_emit(
|
||||
*,
|
||||
last_sig: str | None,
|
||||
last_ts: float,
|
||||
new_sig: str,
|
||||
now_ts: float,
|
||||
min_interval: float,
|
||||
force_interval: float,
|
||||
) -> bool:
|
||||
if last_sig is None:
|
||||
return True
|
||||
if (now_ts - last_ts) >= force_interval:
|
||||
return True
|
||||
if new_sig != last_sig and (now_ts - last_ts) >= min_interval:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def status_push_worker() -> None:
|
||||
"""后台线程:按间隔推送排队/运行中任务的状态更新(可节流)。"""
|
||||
"""后台线程:按间隔推送排队/运行中任务状态(变更驱动+心跳兜底)。"""
|
||||
logger = get_logger()
|
||||
try:
|
||||
push_interval = float(os.environ.get("STATUS_PUSH_INTERVAL_SECONDS", "1"))
|
||||
@@ -18,18 +51,41 @@ def status_push_worker() -> None:
|
||||
push_interval = 1.0
|
||||
push_interval = max(0.5, push_interval)
|
||||
|
||||
try:
|
||||
queue_min_interval = float(os.environ.get("STATUS_PUSH_MIN_QUEUE_INTERVAL_SECONDS", str(push_interval)))
|
||||
except Exception:
|
||||
queue_min_interval = push_interval
|
||||
queue_min_interval = max(push_interval, queue_min_interval)
|
||||
|
||||
try:
|
||||
progress_min_interval = float(
|
||||
os.environ.get("STATUS_PUSH_MIN_PROGRESS_INTERVAL_SECONDS", str(push_interval))
|
||||
)
|
||||
except Exception:
|
||||
progress_min_interval = push_interval
|
||||
progress_min_interval = max(push_interval, progress_min_interval)
|
||||
|
||||
try:
|
||||
force_interval = float(os.environ.get("STATUS_PUSH_FORCE_INTERVAL_SECONDS", "10"))
|
||||
except Exception:
|
||||
force_interval = 10.0
|
||||
force_interval = max(push_interval, force_interval)
|
||||
|
||||
socketio = get_socketio()
|
||||
from services.tasks import get_task_scheduler
|
||||
|
||||
scheduler = get_task_scheduler()
|
||||
emitted_state: dict[str, dict] = {}
|
||||
|
||||
while True:
|
||||
try:
|
||||
now_ts = time.time()
|
||||
queue_snapshot = scheduler.get_queue_state_snapshot()
|
||||
pending_total = int(queue_snapshot.get("pending_total", 0) or 0)
|
||||
running_total = int(queue_snapshot.get("running_total", 0) or 0)
|
||||
running_by_user = queue_snapshot.get("running_by_user") or {}
|
||||
positions = queue_snapshot.get("positions") or {}
|
||||
active_account_ids = set()
|
||||
|
||||
status_items = safe_iter_task_status_items()
|
||||
for account_id, status_info in status_items:
|
||||
@@ -39,11 +95,15 @@ def status_push_worker() -> None:
|
||||
user_id = status_info.get("user_id")
|
||||
if not user_id:
|
||||
continue
|
||||
|
||||
active_account_ids.add(str(account_id))
|
||||
account = safe_get_account(user_id, account_id)
|
||||
if not account:
|
||||
continue
|
||||
|
||||
user_id_int = _to_int(user_id)
|
||||
account_data = account.to_dict()
|
||||
pos = positions.get(account_id) or {}
|
||||
pos = positions.get(account_id) or positions.get(str(account_id)) or {}
|
||||
account_data.update(
|
||||
{
|
||||
"queue_pending_total": pending_total,
|
||||
@@ -51,10 +111,23 @@ def status_push_worker() -> None:
|
||||
"queue_ahead": pos.get("queue_ahead"),
|
||||
"queue_position": pos.get("queue_position"),
|
||||
"queue_is_vip": pos.get("is_vip"),
|
||||
"queue_running_user": int(running_by_user.get(int(user_id), 0) or 0),
|
||||
"queue_running_user": _to_int(running_by_user.get(user_id_int, running_by_user.get(str(user_id_int), 0))),
|
||||
}
|
||||
)
|
||||
socketio.emit("account_update", account_data, room=f"user_{user_id}")
|
||||
|
||||
cache_entry = emitted_state.setdefault(str(account_id), {})
|
||||
account_sig = _payload_signature(account_data)
|
||||
if _should_emit(
|
||||
last_sig=cache_entry.get("account_sig"),
|
||||
last_ts=float(cache_entry.get("account_ts", 0) or 0),
|
||||
new_sig=account_sig,
|
||||
now_ts=now_ts,
|
||||
min_interval=queue_min_interval,
|
||||
force_interval=force_interval,
|
||||
):
|
||||
socketio.emit("account_update", account_data, room=f"user_{user_id}")
|
||||
cache_entry["account_sig"] = account_sig
|
||||
cache_entry["account_ts"] = now_ts
|
||||
|
||||
if status != "运行中":
|
||||
continue
|
||||
@@ -74,9 +147,26 @@ def status_push_worker() -> None:
|
||||
"queue_running_total": running_total,
|
||||
"queue_ahead": pos.get("queue_ahead"),
|
||||
"queue_position": pos.get("queue_position"),
|
||||
"queue_running_user": int(running_by_user.get(int(user_id), 0) or 0),
|
||||
"queue_running_user": _to_int(running_by_user.get(user_id_int, running_by_user.get(str(user_id_int), 0))),
|
||||
}
|
||||
socketio.emit("task_progress", progress_data, room=f"user_{user_id}")
|
||||
|
||||
progress_sig = _payload_signature(progress_data)
|
||||
if _should_emit(
|
||||
last_sig=cache_entry.get("progress_sig"),
|
||||
last_ts=float(cache_entry.get("progress_ts", 0) or 0),
|
||||
new_sig=progress_sig,
|
||||
now_ts=now_ts,
|
||||
min_interval=progress_min_interval,
|
||||
force_interval=force_interval,
|
||||
):
|
||||
socketio.emit("task_progress", progress_data, room=f"user_{user_id}")
|
||||
cache_entry["progress_sig"] = progress_sig
|
||||
cache_entry["progress_ts"] = now_ts
|
||||
|
||||
if emitted_state:
|
||||
stale_ids = [account_id for account_id in emitted_state.keys() if account_id not in active_account_ids]
|
||||
for account_id in stale_ids:
|
||||
emitted_state.pop(account_id, None)
|
||||
|
||||
time.sleep(push_interval)
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user