Milestone alpha3
This commit is contained in:
83
main.py
83
main.py
@@ -14,7 +14,7 @@ import time
|
||||
import customtkinter as ctk
|
||||
from tkinter import messagebox
|
||||
|
||||
from async_loop_singleton import get_global_loop
|
||||
from async_loop_singleton import get_global_loop, stop_global_loop
|
||||
from async_msssql_query import AsyncMSSQLClient
|
||||
from audit_log import log_session_event
|
||||
from db_config import build_dsn_from_config, ensure_db_config
|
||||
@@ -45,12 +45,6 @@ BYPASS_LOGIN_USER = {
|
||||
"codice_unita": "U1",
|
||||
}
|
||||
|
||||
if sys.platform.startswith("win"):
|
||||
try:
|
||||
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Create one global loop and make it the default everywhere.
|
||||
_loop = get_global_loop()
|
||||
asyncio.set_event_loop(_loop)
|
||||
@@ -71,6 +65,51 @@ _APP_MUTEX = None
|
||||
_APP_MUTEX_NAME = "Local\\WarehousePythonAppSingleton"
|
||||
|
||||
|
||||
def _dispose_db_client() -> None:
|
||||
"""Best-effort disposal of the shared DB client."""
|
||||
|
||||
global db_app
|
||||
if db_app is None:
|
||||
return
|
||||
try:
|
||||
fut = asyncio.run_coroutine_threadsafe(db_app.dispose(), _loop)
|
||||
try:
|
||||
fut.result(timeout=2)
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
db_app = None
|
||||
|
||||
|
||||
def _destroy_tk_root(root: tk.Misc | None) -> None:
|
||||
"""Destroy a hidden bootstrap root without leaking a Tk interpreter."""
|
||||
|
||||
if root is None:
|
||||
return
|
||||
try:
|
||||
root.quit()
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
root.destroy()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _shutdown_runtime(*, bootstrap: tk.Misc | None = None, dispose_db: bool = True) -> None:
|
||||
"""Release temporary Tk resources, DB client and background loop."""
|
||||
|
||||
try:
|
||||
_destroy_tk_root(bootstrap)
|
||||
finally:
|
||||
if dispose_db:
|
||||
_dispose_db_client()
|
||||
try:
|
||||
stop_global_loop()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _acquire_single_instance_mutex() -> bool:
|
||||
"""Return ``True`` only for the first running instance of the application."""
|
||||
|
||||
@@ -435,14 +474,19 @@ if __name__ == "__main__":
|
||||
),
|
||||
parent=root,
|
||||
)
|
||||
_destroy_tk_root(root)
|
||||
try:
|
||||
root.destroy()
|
||||
stop_global_loop()
|
||||
except Exception:
|
||||
pass
|
||||
raise SystemExit(0)
|
||||
|
||||
db_cfg = ensure_db_config(_loop)
|
||||
if db_cfg is None:
|
||||
try:
|
||||
stop_global_loop()
|
||||
except Exception:
|
||||
pass
|
||||
raise SystemExit(0)
|
||||
|
||||
db_app = AsyncMSSQLClient(build_dsn_from_config(db_cfg))
|
||||
@@ -466,23 +510,12 @@ if __name__ == "__main__":
|
||||
session = prompt_login(bootstrap, db_app)
|
||||
|
||||
if session is None:
|
||||
if db_app is not None:
|
||||
fut = asyncio.run_coroutine_threadsafe(db_app.dispose(), _loop)
|
||||
try:
|
||||
fut.result(timeout=2)
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
if bootstrap is not None:
|
||||
bootstrap.destroy()
|
||||
except Exception:
|
||||
pass
|
||||
_shutdown_runtime(bootstrap=bootstrap, dispose_db=True)
|
||||
raise SystemExit(0)
|
||||
|
||||
try:
|
||||
if bootstrap is not None:
|
||||
bootstrap.destroy()
|
||||
except Exception:
|
||||
pass
|
||||
_destroy_tk_root(bootstrap)
|
||||
|
||||
Launcher(session, db_app).mainloop()
|
||||
try:
|
||||
Launcher(session, db_app).mainloop()
|
||||
finally:
|
||||
_shutdown_runtime(bootstrap=None, dispose_db=True)
|
||||
|
||||
Reference in New Issue
Block a user