код написан
This commit is contained in:
@@ -8,9 +8,13 @@
|
||||
# [SECTION: IMPORTS]
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
from apscheduler.triggers.date import DateTrigger
|
||||
from .logger import logger, belief_scope
|
||||
from .config_manager import ConfigManager
|
||||
from .database import SessionLocal
|
||||
from ..models.llm import ValidationPolicy
|
||||
import asyncio
|
||||
from datetime import datetime, time, timedelta, date
|
||||
# [/SECTION]
|
||||
|
||||
# [DEF:SchedulerService:Class]
|
||||
@@ -117,4 +121,63 @@ class SchedulerService:
|
||||
# [/DEF:_trigger_backup:Function]
|
||||
|
||||
# [/DEF:SchedulerService:Class]
|
||||
|
||||
# [DEF:ThrottledSchedulerConfigurator:Class]
|
||||
# @TIER: CRITICAL
|
||||
# @SEMANTICS: scheduler, throttling, distribution
|
||||
# @PURPOSE: Distributes validation tasks evenly within an execution window.
|
||||
class ThrottledSchedulerConfigurator:
|
||||
# [DEF:calculate_schedule:Function]
|
||||
# @PURPOSE: Calculates execution times for N tasks within a window.
|
||||
# @PRE: window_start, window_end (time), dashboard_ids (List), current_date (date).
|
||||
# @POST: Returns List[datetime] of scheduled times.
|
||||
# @INVARIANT: Tasks are distributed with near-even spacing.
|
||||
@staticmethod
|
||||
def calculate_schedule(
|
||||
window_start: time,
|
||||
window_end: time,
|
||||
dashboard_ids: list,
|
||||
current_date: date
|
||||
) -> list:
|
||||
with belief_scope("ThrottledSchedulerConfigurator.calculate_schedule"):
|
||||
n = len(dashboard_ids)
|
||||
if n == 0:
|
||||
return []
|
||||
|
||||
start_dt = datetime.combine(current_date, window_start)
|
||||
end_dt = datetime.combine(current_date, window_end)
|
||||
|
||||
# Handle window crossing midnight
|
||||
if end_dt < start_dt:
|
||||
end_dt += timedelta(days=1)
|
||||
|
||||
total_seconds = (end_dt - start_dt).total_seconds()
|
||||
|
||||
# Minimum interval of 1 second to avoid division by zero or negative
|
||||
if total_seconds <= 0:
|
||||
logger.warning(f"[calculate_schedule] Window size is zero or negative. Falling back to start time for all {n} tasks.")
|
||||
return [start_dt] * n
|
||||
|
||||
# If window is too small for even distribution (e.g. 10 tasks in 5 seconds),
|
||||
# we still distribute them but they might be very close.
|
||||
# The requirement says "near-even spacing".
|
||||
|
||||
if n == 1:
|
||||
return [start_dt]
|
||||
|
||||
interval = total_seconds / (n - 1) if n > 1 else 0
|
||||
|
||||
# If interval is too small (e.g. < 1s), we might want a fallback,
|
||||
# but the spec says "handle too-small windows with explicit fallback/warning".
|
||||
if interval < 1:
|
||||
logger.warning(f"[calculate_schedule] Window too small for {n} tasks (interval {interval:.2f}s). Tasks will be highly concentrated.")
|
||||
|
||||
scheduled_times = []
|
||||
for i in range(n):
|
||||
scheduled_times.append(start_dt + timedelta(seconds=i * interval))
|
||||
|
||||
return scheduled_times
|
||||
# [/DEF:calculate_schedule:Function]
|
||||
# [/DEF:ThrottledSchedulerConfigurator:Class]
|
||||
|
||||
# [/DEF:SchedulerModule:Module]
|
||||
Reference in New Issue
Block a user