From 49ebd75522d02e83130174c019ff0502a1114755 Mon Sep 17 00:00:00 2001 From: OpenSquared Date: Fri, 31 Jul 2026 09:40:55 +0200 Subject: [PATCH] feat: strategy builder --- backend/services/database.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/services/database.py b/backend/services/database.py index c0953d3..56afd48 100644 --- a/backend/services/database.py +++ b/backend/services/database.py @@ -11,7 +11,16 @@ DB_PATH = os.path.join(os.path.dirname(__file__), "..", "data", "geooptions.db") def get_conn() -> sqlite3.Connection: - conn = sqlite3.connect(DB_PATH) + # WAL mode lets readers and a writer proceed concurrently instead of taking the default + # rollback-journal's exclusive lock on every write — with several background schedulers + # (Saxo snapshots, wavelet refresh, macro gauge...) hitting this same file, that exclusive + # lock is what surfaces as "sqlite3.OperationalError: database is locked". busy_timeout is + # the second line of defense: a connection that still finds the file locked waits (up to + # 30s) instead of raising immediately, covering any writer that briefly holds it even + # under WAL (a concurrent writer, not readers). + conn = sqlite3.connect(DB_PATH, timeout=30) + conn.execute("PRAGMA journal_mode=WAL") + conn.execute("PRAGMA busy_timeout=30000") conn.row_factory = sqlite3.Row return conn