2bbdb00a4d
包含节点账本、每日清算,以及 Ubuntu 交互式部署脚本。 Co-authored-by: Cursor <cursoragent@cursor.com>
42 lines
1.5 KiB
Python
42 lines
1.5 KiB
Python
"""每天凌晨的积分清算任务。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from datetime import date, datetime, timedelta, timezone
|
|
|
|
from app.clock import utcnow
|
|
from app.database import session_scope
|
|
from app.services.heartbeat import mark_stale_nodes
|
|
from app.services.yield_engine import SettleSummary, settle_yield_date
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def run_daily_yield_cron(now: datetime | None = None, yield_date: date | None = None) -> SettleSummary:
|
|
"""计算所有仍在授权期内的节点,并把当日积分写入 node_yields。
|
|
|
|
调度器在北京时间 00:05 调用本函数。账本按 UTC 日切分,因此入账日期是
|
|
调用时刻之前最近一个已经结束的 UTC 日,而不是刚开始的这一天。
|
|
同一节点同一天已有流水时跳过,重复触发不会重复入账。
|
|
"""
|
|
moment = now or utcnow()
|
|
if moment.tzinfo is None:
|
|
raise ValueError("清算时间必须带时区")
|
|
target = yield_date or (moment.astimezone(timezone.utc).date() - timedelta(days=1))
|
|
|
|
with session_scope() as session:
|
|
stale = mark_stale_nodes(session, moment)
|
|
summary = settle_yield_date(session, target, moment)
|
|
|
|
logger.info(
|
|
"daily yield settled date=%s created=%s skipped=%s points=%s partial=%s stale_nodes=%s",
|
|
summary.yield_date,
|
|
summary.created,
|
|
summary.skipped,
|
|
format(summary.total_points, "f"),
|
|
summary.is_partial,
|
|
len(stale),
|
|
)
|
|
return summary
|