diff --git a/backend/db.py b/backend/db.py index 8db513c..9a6f5f6 100644 --- a/backend/db.py +++ b/backend/db.py @@ -14,6 +14,7 @@ MariaDB automatically. Upserts must use backend-specific SQL (see services). """ import os import sqlite3 +import time import threading import queue import datetime @@ -511,8 +512,35 @@ def _statements(schema): yield stmt +# How long to keep waiting for the database at startup. +# +# On a NAS reboot the app and MariaDB come up together and the app usually +# wins the race. Without this it raised, gunicorn reported "Worker failed to +# boot", the master shut down — and when MariaDB appeared seconds later there +# was nothing left running to notice. The site stayed down until someone +# restarted it by hand. +INIT_RETRY_SECONDS = int(os.environ.get("DB_INIT_RETRY_SECONDS") or 120) +INIT_RETRY_INTERVAL = 3 + + def init_db(): - conn = _connect() + deadline = time.monotonic() + INIT_RETRY_SECONDS + attempt = 0 + while True: + attempt += 1 + try: + conn = _connect() + break + except Exception as e: # noqa: BLE001 - any connection failure is worth retrying + if time.monotonic() >= deadline: + raise + if attempt == 1: + print(f"[db] 数据库还没准备好,重试中:{e}") + time.sleep(INIT_RETRY_INTERVAL) + + if attempt > 1: + print(f"[db] 第 {attempt} 次尝试后连上数据库") + try: cur = conn.cursor() for stmt in _statements(SCHEMA):