ForcePilot/backend/package/yuxi/scheduler/use_cases/utils/backoff.py
Kris 6498af03e3 feat(scheduler): 完整实现定时任务调度限界上下文基础架构
本次提交完成了定时任务调度限界上下文的全量基础架构搭建,包括:
1.  基于六边形架构的完整分层(core/use_cases/framework/adapters/infrastructure)
2.  任务调度核心领域模型、端口契约与校验工具
3.  持久化适配器层与SQLAlchemy仓储实现
4.  调度运行时核心组件(handler注册表、执行引擎)
5.  内置维护型任务handler(日志清理、幂等记录清理)
6.  全局异常处理器与PostgreSQL表结构适配
7.  ARQ worker调度任务集成与启动装配逻辑
2026-06-22 20:07:20 +08:00

70 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""指数退避计算工具。
本模块提供两个函数:
- ``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)