Небольшие изменения
This commit is contained in:
@@ -7,9 +7,12 @@ import time as time_module
|
||||
|
||||
from app.core.logging import migration_logger
|
||||
from app.core.config import settings
|
||||
from app.models.replication import ReplicationSchedule
|
||||
from app.services.batch_runner import get_tables_to_run, run_migration_batch
|
||||
from app.services.migrator import migrator
|
||||
from app.repository.replication_metadata_repo import replication_metadata_repo
|
||||
from app.utils.email_sender import email_sender
|
||||
from app.core.database import db_connector
|
||||
|
||||
|
||||
class MigrationScheduler:
|
||||
@@ -24,7 +27,8 @@ class MigrationScheduler:
|
||||
|
||||
def _init_default_schedules(self):
|
||||
"""Инициализация расписаний по умолчанию"""
|
||||
self.repo.init_default_schedules(settings.TABLES_TO_COPY)
|
||||
metadatas = self.repo.get_all_metadata()
|
||||
self.repo.init_default_schedules(metadatas)
|
||||
migration_logger.info("Расписания по умолчанию инициализированы")
|
||||
|
||||
def set_schedule(self, table_name: str, schedule_time: str = "00:00",
|
||||
@@ -71,95 +75,35 @@ class MigrationScheduler:
|
||||
"""Включить расписание"""
|
||||
self.repo.enable_schedule(table_name)
|
||||
|
||||
def delete_schedule(self, table_name: str):
|
||||
def delete_schedule(self, schedule_id: int):
|
||||
"""Удалить расписание"""
|
||||
self.repo.delete_schedule(table_name)
|
||||
self.repo.delete_schedule(schedule_id)
|
||||
|
||||
def get_due_tables(self, current_time: Optional[datetime] = None) -> List:
|
||||
def get_due_tables(self, current_time: Optional[datetime] = None) -> List[ReplicationSchedule]:
|
||||
"""Получить таблицы для запуска сейчас"""
|
||||
due = self.repo.get_due_schedules(current_time)
|
||||
return due
|
||||
|
||||
async def run_due_migrations(self):
|
||||
"""Запустить миграции по расписанию"""
|
||||
due_schedules = self.get_due_tables()
|
||||
async def check_and_run_schedules(self):
|
||||
"""
|
||||
Проверить расписания и запустить задачи.
|
||||
Вызывается по cron (например, каждую минуту).
|
||||
"""
|
||||
migration_logger.info("Проверка расписаний миграции...")
|
||||
|
||||
if not due_schedules:
|
||||
return
|
||||
try:
|
||||
async with db_connector.async_dst_session() as session:
|
||||
tables = await get_tables_to_run(session)
|
||||
|
||||
if tables:
|
||||
batch_id = await run_migration_batch(tables)
|
||||
migration_logger.info(f"Батч запущен: {batch_id}")
|
||||
else:
|
||||
migration_logger.info("Нет задач для запуска в это время")
|
||||
|
||||
migration_logger.info(f"Найдено {len(due_schedules)} таблиц для миграции по расписанию")
|
||||
|
||||
for schedule in due_schedules:
|
||||
try:
|
||||
days_str = ', '.join(schedule.days_display)
|
||||
migration_logger.info(
|
||||
f"Запуск миграции по расписанию для {schedule.table_name} "
|
||||
f"в {schedule.schedule_time.strftime('%H:%M')} [{days_str}]"
|
||||
)
|
||||
|
||||
# Запускаем миграцию
|
||||
result = await asyncio.to_thread(
|
||||
migrator.run_migration,
|
||||
tables=[schedule.table_name],
|
||||
full_reload=schedule.full_reload,
|
||||
send_email=True
|
||||
)
|
||||
|
||||
# Обновляем время последнего запуска
|
||||
self.repo.update_schedule_last_run(schedule.table_name)
|
||||
|
||||
# Логируем успешный запуск
|
||||
self.repo.log_operation(
|
||||
table_name=schedule.table_name,
|
||||
operation='SCHEDULED',
|
||||
records_count=0,
|
||||
status='SUCCESS'
|
||||
)
|
||||
|
||||
migration_logger.info(f"Миграция по расписанию для {schedule.table_name} завершена")
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"Ошибка при миграции по расписанию для {schedule.table_name}: {e}"
|
||||
migration_logger.error(error_msg)
|
||||
|
||||
# Логируем ошибку
|
||||
self.repo.log_operation(
|
||||
table_name=schedule.table_name,
|
||||
operation='SCHEDULED',
|
||||
records_count=0,
|
||||
status='ERROR',
|
||||
error_message=str(e)[:500]
|
||||
)
|
||||
|
||||
email_sender.send_error_notification(
|
||||
error_message=error_msg,
|
||||
table_name=schedule.table_name
|
||||
)
|
||||
|
||||
def start_scheduler(self):
|
||||
"""Запустить планировщик"""
|
||||
self.running = True
|
||||
migration_logger.info("Планировщик миграций запущен")
|
||||
|
||||
while self.running:
|
||||
try:
|
||||
# Проверяем, есть ли таблицы для миграции
|
||||
asyncio.run(self.run_due_migrations())
|
||||
|
||||
# Ждем 60 секунд до следующей проверки
|
||||
time_module.sleep(60)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
self.stop_scheduler()
|
||||
break
|
||||
except Exception as e:
|
||||
migration_logger.error(f"Ошибка в планировщике: {e}")
|
||||
time_module.sleep(60)
|
||||
|
||||
def stop_scheduler(self):
|
||||
"""Остановить планировщик"""
|
||||
self.running = False
|
||||
migration_logger.info("Планировщик миграций остановлен")
|
||||
except Exception as e:
|
||||
migration_logger.error(f"Ошибка проверки расписаний: {e}")
|
||||
raise
|
||||
|
||||
|
||||
# Глобальный экземпляр
|
||||
|
||||
Reference in New Issue
Block a user