73 lines
3.0 KiB
Python
73 lines
3.0 KiB
Python
import asyncio
|
||
import redis.asyncio as redis
|
||
from taskiq import ScheduledTask
|
||
|
||
from app.taskiq.broker import broker, scheduler, schedule_source, migrate_table_task
|
||
from app.core.logging import migration_logger
|
||
|
||
REDIS_URL = "redis://127.0.0.1:6379"
|
||
PREFIX = "migration_schedule"
|
||
|
||
async def sync_schedules_to_redis():
|
||
"""Полная перезапись расписаний в Redis на основе данных из БД."""
|
||
migration_logger.info("Синхронизация расписаний с Redis...")
|
||
|
||
# 1. Получаем все активные расписания из БД через database.py
|
||
from app.core.database import db_connector
|
||
from app.models.replication import ReplicationSchedule
|
||
|
||
# Инициализируем engine и session (обращение к свойству создает sessionmaker)
|
||
_ = db_connector.dst_engine
|
||
SessionLocal = db_connector.dst_session
|
||
session = SessionLocal()
|
||
|
||
try:
|
||
schedules = session.query(ReplicationSchedule).filter(
|
||
ReplicationSchedule.enabled == True
|
||
).all()
|
||
|
||
# 2. Очищаем все старые ключи расписаний в Redis
|
||
r = await redis.from_url(REDIS_URL)
|
||
keys = await r.keys(f"{PREFIX}:*")
|
||
if keys:
|
||
await r.delete(*keys)
|
||
await r.close()
|
||
|
||
# 3. Добавляем каждое расписание через add_schedule
|
||
added = 0
|
||
for schedule in schedules:
|
||
hour = schedule.schedule_time.hour
|
||
minute = schedule.schedule_time.minute
|
||
days_list = schedule.days_list # список чисел 0..6
|
||
|
||
# Формируем cron-выражение
|
||
if days_list:
|
||
cron_expr = f"{minute} {hour} * * {','.join(map(str, days_list))}"
|
||
else:
|
||
cron_expr = f"{minute} {hour} * * *"
|
||
|
||
# Используем timezone string для cron_offset (UTC+9 = Asia/Tokyo)
|
||
task = ScheduledTask(
|
||
task_name="migrate_table_task",
|
||
labels={},
|
||
cron=cron_expr,
|
||
cron_offset='Asia/Tokyo', # Timezone name для UTC+9
|
||
args=[schedule.table_name],
|
||
kwargs={"full_reload": schedule.full_reload}
|
||
)
|
||
|
||
# Добавляем в Redis через источник
|
||
await schedule_source.add_schedule(task)
|
||
added += 1
|
||
migration_logger.info(f"Добавлено: {schedule.table_name} в {hour:02d}:{minute:02d} (cron: {cron_expr})")
|
||
|
||
migration_logger.info(f"Синхронизировано {added} активных расписаний")
|
||
finally:
|
||
session.close()
|
||
|
||
|
||
async def on_scheduler_startup():
|
||
"""Хук для синхронизации расписаний при запуске планировщика."""
|
||
migration_logger.info("Запуск планировщика taskiq...")
|
||
await sync_schedules_to_redis()
|
||
migration_logger.info("Планировщик готов к работе") |