11"""
22 Watchdog для мониторинга и прерывания длительных обработок попыток и их прерывания
3- Запускать как отдельный сервис. Два значения читаются из конфига - макс. время попытки и интервал проверок
3+ Запускать как отдельный сервис
4+
5+ Два значения читаются из конфига - макс. время попытки и интервал проверок
46 [constants]
57 processing_limit = ()
68 interval_time = ()
9+
10+ Взаимодействие с базой данных:
11+ - Использует TrainingsDBManager для доступа к тренировкам
12+ - Находит все тренировки, у которых задано поле `processing_start_timestamp`
13+ - Если прошло больше processing_limit секунд:
14+ * Добавляет в базу вердикт с комментарием "обратиться к администраторам" через append_verdict()
15+ * Устанавливает оценку 0 через set_score()
16+ * Меняет статусы presentation и audio на PROCESSING_FAILED, если они ещё не финальные
17+ - После каждой итерации ждёт interval_time секунд и повторяет проверку
718"""
819
920import time
2233def get_config_values ():
2334 try :
2435 return int (Config .c .constants .processing_limit ), int (Config .c .constants .interval_time )
25- except Exception :
36+ except Exception as e :
37+ logger .warning ("Failed to read config values, using defaults: %s" , e )
2638 return DEFAULT_MAX_SECONDS , DEFAULT_INTERVAL_SECONDS
2739
2840def time_now ():
@@ -42,8 +54,8 @@ def run_once(max_seconds):
4254 continue
4355 try :
4456 started = datetime .fromtimestamp (process_started .time , timezone .utc )
45- except Exception :
46- continue
57+ except Exception as e :
58+ logger . warning ( "Invalid timestamp in training %s: %s" , getattr ( training , "_id" , "?" ), e )
4759 elapsed = (now - started ).total_seconds ()
4860 if elapsed <= max_seconds :
4961 continue
@@ -66,25 +78,25 @@ def run_once(max_seconds):
6678 pres_status = getattr (training , "presentation_status" , None )
6779 if pres_status not in [PresentationStatus .PROCESSED , PresentationStatus .PROCESSING_FAILED ]:
6880 TrainingsDBManager ().change_presentation_status (training_id , PresentationStatus .PROCESSING_FAILED )
69- except Exception :
70- logger .exception ("Failed to mark presentation status as failed for training %s" , training_id )
81+ except Exception as e :
82+ logger .exception ("Failed to mark presentation status as failed for training %s: %s " , training_id , e )
7183 try :
7284 audio_status = getattr (training , "audio_status" , None )
7385 if audio_status not in [AudioStatus .PROCESSED , AudioStatus .PROCESSING_FAILED ]:
7486 TrainingsDBManager ().change_audio_status (training_id , AudioStatus .PROCESSING_FAILED )
75- except Exception :
76- logger .exception ("Failed to mark audio status as failed for training %s" , training_id )
77- except Exception :
78- logger .exception ("Error while handling timeout for training %s" , training_id )
87+ except Exception as e :
88+ logger .exception ("Failed to mark audio status as failed for training %s: %s " , training_id , e )
89+ except Exception as e :
90+ logger .exception ("Error while handling timeout for training %s: %s " , training_id , e )
7991
8092def run ():
8193 max_seconds , interval_time = get_config_values ()
8294 logger .info ("Processing watchdog started. Timeout = %s s, interval time = %s s" , max_seconds , interval_time )
8395 while True :
8496 try :
8597 run_once (max_seconds )
86- except Exception :
87- logger .exception ("Unhandled error in processing watchdog main loop" )
98+ except Exception as e :
99+ logger .exception ("Unhandled error in processing watchdog main loop (%s)" , e )
88100 time .sleep (interval_time )
89101
90102if __name__ == "__main__" :
0 commit comments