Current State
Related to #947
Problem
Several background jobs switch the app-wide database with init_db(target) from a worker thread and restore it afterwards:
GsakImportWorker (gsak_import_dialog.py)
ImportWorker (import_dialog.py)
_MoveWorker (move_caches_dialog.py)
_import_zip_bytes (email/service.py)
The dialogs are modal, but that only blocks user input. The GUI thread keeps running timers and queued signals (e.g. the search timer, the 5 s/7 s startup checks in mainwindow.py). Anything that calls get_session() while a worker has the target DB active reads from, or writes to, the wrong database.
In addition, init_db() replaces _engine without disposing the old one (database.py), so a multi-database import leaves 2×N engines, each with its own open SQLite connections.
Related: import_gpx() / import_zip() ignore the session passed in and always open their own via make_session() on the active DB. They only write to the right database because of the global swap.
Proposed Improvement
Proposed fix
- Add
session_for(path) in database.py: a context-managed session on a private engine for that file (schema created/migrated like init_db()), disposed on exit. Globals untouched.
- Use it in the four callers above whenever the target isn't the active DB; drop the switch/restore logic.
- Let
import_gpx() / import_zip() open their internal session on the same engine as the session they're given.
- Make
init_db() dispose the engine it replaces.
Kept separate from the GSAK import feature work, as it's an architectural cleanup touching several dialogs.
Expected Benefits
No response
Current State
Related to #947
Problem
Several background jobs switch the app-wide database with
init_db(target)from a worker thread and restore it afterwards:GsakImportWorker(gsak_import_dialog.py)ImportWorker(import_dialog.py)_MoveWorker(move_caches_dialog.py)_import_zip_bytes(email/service.py)The dialogs are modal, but that only blocks user input. The GUI thread keeps running timers and queued signals (e.g. the search timer, the 5 s/7 s startup checks in
mainwindow.py). Anything that callsget_session()while a worker has the target DB active reads from, or writes to, the wrong database.In addition,
init_db()replaces_enginewithout disposing the old one (database.py), so a multi-database import leaves 2×N engines, each with its own open SQLite connections.Related:
import_gpx()/import_zip()ignore the session passed in and always open their own viamake_session()on the active DB. They only write to the right database because of the global swap.Proposed Improvement
Proposed fix
session_for(path)indatabase.py: a context-managed session on a private engine for that file (schema created/migrated likeinit_db()), disposed on exit. Globals untouched.import_gpx()/import_zip()open their internal session on the same engine as the session they're given.init_db()dispose the engine it replaces.Kept separate from the GSAK import feature work, as it's an architectural cleanup touching several dialogs.
Expected Benefits
No response