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("Планировщик готов к работе")