70 lines
2.8 KiB
Python
70 lines
2.8 KiB
Python
import subprocess
|
||
import signal
|
||
|
||
class WorkerManager:
|
||
def __init__(self, shutdown_timeout=5):
|
||
self.process = None
|
||
self.running = False
|
||
self.shutdown_timeout = shutdown_timeout
|
||
|
||
def start_worker(self):
|
||
"""Запуск воркера"""
|
||
cmd = [
|
||
"taskiq", "worker",
|
||
"app.taskiq.broker:broker",
|
||
"--workers", "1",
|
||
"--max-prefetch", "1",
|
||
]
|
||
|
||
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_worker()
|
||
except Exception as e:
|
||
print(f"Ошибка при ожидании воркера: {e}")
|
||
self.stop_worker()
|
||
|
||
def _signal_handler(self, sig, frame):
|
||
"""Обработчик сигнала остановки"""
|
||
print(f"\nПолучен сигнал {sig}, останавливаю воркер...")
|
||
self.stop_worker()
|
||
|
||
def stop_worker(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 = WorkerManager(shutdown_timeout=3)
|
||
manager.start_worker()
|
||
|
||
if __name__ == "__main__":
|
||
main() |