fix: ограничить время запросов и исключить параллельные запуски

Добавлены таймауты запросов к сайту и Telegram, общий предел выполнения 9 минут и файловая блокировка запусков. База сообщений сохраняется атомарно. Регрессионные тесты запускаются перед публикацией Docker-образа.
This commit is contained in:
serega404 committed 2026-10-28 18:11:59 +03:00
1 parent 6f2b27f00e
commit c5c4a63668
5 files changed
+201 -5

No files matched your search

+26 -1
View File
@@ -1,9 +1,13 @@
import fcntl
import os
import signal
from parser import create_session, publish_new_posts
URL = os.environ.get('VODOKANAL_URL', 'http://www.tgnvoda.ru/avarii.php')
RUN_TIMEOUT_SECONDS = 9 * 60
TELEGRAM_TIMEOUT = 60
SEND_SILENT = os.environ.get('SEND_SILENT', False)
TELEGRAM_TOKEN = os.environ.get('TELEGRAM_TOKEN', '')
TELEGRAM_CHANNEL = os.environ.get('TELEGRAM_CHANNEL', '')
@@ -18,6 +22,7 @@ def send_telegram_message(session, message):
'disable_notification': str(SEND_SILENT),
'text': message,
},
timeout=TELEGRAM_TIMEOUT,
)
if (req.status_code != 200):
print("Telegram request error: " + str(req.status_code))
@@ -47,5 +52,25 @@ def main():
exit()
def _stop_overdue_run(signum, frame):
raise SystemExit(f"Bot run exceeded time limit ({RUN_TIMEOUT_SECONDS} seconds)")
def run_once(lock_path="/tmp/vodokanalbot.lock"):
with open(lock_path, "a") as lock:
try:
fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
except BlockingIOError:
print("Previous run is still active; skipping")
return
previous_handler = signal.signal(signal.SIGALRM, _stop_overdue_run)
try:
signal.alarm(RUN_TIMEOUT_SECONDS)
main()
finally:
signal.alarm(0)
signal.signal(signal.SIGALRM, previous_handler)
if __name__ == "__main__":
main()
run_once()