import subprocess import signal class ScheduleManager: def __init__(self, shutdown_timeout=5): self.process = None self.running = False self.shutdown_timeout = shutdown_timeout def start_schedule(self): """Запуск расписания""" cmd = [ "taskiq", "scheduler", "app.taskiq.broker:scheduler" ] print("Запуск расписания...") self.process = subprocess.Popen(cmd) self.running = True # Установить обработчики сигналов signal.signal(signal.SIGINT, self._signal_handler) signal.signal(signal.SIGTERM, self._signal_handler) try: return_code = self.process.wait() print(f"Расписание завершилось с кодом: {return_code}") except KeyboardInterrupt: print("Получен SIGINT, останавливаем...") self.stop_schedule() except Exception as e: print(f"Ошибка при ожидании расписания: {e}") self.stop_schedule() def _signal_handler(self, sig, frame): """Обработчик сигнала остановки""" print(f"\nПолучен сигнал {sig}, останавливаю расприсание...") self.stop_schedule() def stop_schedule(self): """Корректная остановка расписания""" if self.process and self.running: print("Отправляем SIGTERM расприсанию...") self.process.terminate() try: # Ждать завершения в течение self.shutdown_timeout секунд return_code = self.process.wait(timeout=self.shutdown_timeout) print(f"Расприсание завершилось с кодом: {return_code}") except subprocess.TimeoutExpired: print(f"Расприсание не завершилось за {self.shutdown_timeout} секунд, отправляем SIGKILL...") self.process.kill() try: self.process.wait(timeout=2) # 2 секунды на SIGKILL print("Процесс принудительно завершен") except subprocess.TimeoutExpired: print("Не удалось завершить процесс принудительно") self.running = False print("Расприсание остановлено") def main(): # Использовать короткий таймаут manager = ScheduleManager(shutdown_timeout=3) manager.start_schedule() if __name__ == "__main__": main()