本次提交完成了定时任务调度限界上下文的全量基础架构搭建,包括: 1. 基于六边形架构的完整分层(core/use_cases/framework/adapters/infrastructure) 2. 任务调度核心领域模型、端口契约与校验工具 3. 持久化适配器层与SQLAlchemy仓储实现 4. 调度运行时核心组件(handler注册表、执行引擎) 5. 内置维护型任务handler(日志清理、幂等记录清理) 6. 全局异常处理器与PostgreSQL表结构适配 7. ARQ worker调度任务集成与启动装配逻辑
70 lines
2.4 KiB
Python
70 lines
2.4 KiB
Python
"""指数退避计算工具。
|
||
|
||
本模块提供两个函数:
|
||
|
||
- ``calc_backoff_seconds``:根据连续错误数从退避序列取退避秒数。
|
||
- ``calc_backoff_next_run_at``:计算退避后的下次运行时间。
|
||
|
||
设计要点(见设计方案 §8.2):
|
||
|
||
- 退避序列由配置 ``scheduler_backoff_schedule`` 提供(如 ``[10, 30, 120, 600, 3600]``)。
|
||
- 根据 ``consecutive_errors`` 从序列取值,超过序列长度时取最后一个值。
|
||
- ``consecutive_errors`` 为 0 时返回 0(无退避)。
|
||
- 时间计算基于 ``utc_now_naive()``,结果为 UTC naive datetime。
|
||
- 纯函数,不依赖框架层组件。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from datetime import datetime, timedelta
|
||
|
||
from yuxi.utils.datetime_utils import utc_now_naive
|
||
|
||
|
||
def calc_backoff_seconds(consecutive_errors: int, schedule: list[int]) -> int:
|
||
"""根据连续错误数计算退避秒数。
|
||
|
||
Args:
|
||
consecutive_errors: 连续错误次数。
|
||
schedule: 退避时间表(秒),如 ``[60, 300, 1800, 7200]``。
|
||
|
||
Returns:
|
||
退避秒数,超过 ``schedule`` 长度时取最后一个值。
|
||
|
||
说明:
|
||
- ``consecutive_errors <= 0`` 时返回 0(无退避)。
|
||
- ``consecutive_errors`` 在 ``[1, len(schedule)]`` 范围内时,取
|
||
``schedule[consecutive_errors - 1]``。
|
||
- ``consecutive_errors`` 超过序列长度时,取 ``schedule[-1]``(封顶)。
|
||
- ``schedule`` 为空时返回 0。
|
||
"""
|
||
if consecutive_errors <= 0 or not schedule:
|
||
return 0
|
||
index = min(consecutive_errors, len(schedule)) - 1
|
||
return schedule[index]
|
||
|
||
|
||
def calc_backoff_next_run_at(
|
||
consecutive_errors: int,
|
||
schedule: list[int],
|
||
*,
|
||
base_time: datetime | None = None,
|
||
) -> datetime:
|
||
"""计算退避后的下次运行时间。
|
||
|
||
Args:
|
||
consecutive_errors: 连续错误次数。
|
||
schedule: 退避时间表(秒)。
|
||
base_time: 基准时间(UTC naive),默认 ``utc_now_naive()``。
|
||
|
||
Returns:
|
||
UTC naive datetime,退避后的下次运行时间。
|
||
|
||
说明:
|
||
``consecutive_errors`` 为 0 时退避秒数为 0,返回 ``base_time``
|
||
(或当前 UTC 时间)。
|
||
"""
|
||
base = base_time if base_time is not None else utc_now_naive()
|
||
seconds = calc_backoff_seconds(consecutive_errors, schedule)
|
||
return base + timedelta(seconds=seconds)
|