Skip to content

Commit 62b8aaf

Browse files
committed
feat: close dbs when about to exit
- This will close connections, truncate WAL files and drain the db cache
1 parent 868ae17 commit 62b8aaf

3 files changed

Lines changed: 50 additions & 2 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ time = "0.3.44"
2424
tokio = { version = "1.48.0", features = ["sync"] }
2525
indexmap = { version = "2.12.1", features = ["serde"] }
2626
base64 = "0.22.1"
27+
tracing = { version = "0.1.41", default-features = false, features = ["std", "release_max_level_off"] }
2728

2829
# SQLx for types and queries (time feature enables datetime type decoding)
2930
sqlx = { version = "0.8.6", features = ["sqlite", "json", "time", "runtime-tokio"] }

src/lib.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::collections::HashMap;
22

3-
use tauri::{Manager, Runtime, plugin::Builder as PluginBuilder};
3+
use tauri::{Manager, RunEvent, Runtime, plugin::Builder as PluginBuilder};
44
use tokio::sync::RwLock;
5+
use tracing::{debug, info, warn};
56

67
mod commands;
78
mod decode;
@@ -57,10 +58,55 @@ impl Builder {
5758
])
5859
.setup(|app, _api| {
5960
app.manage(DbInstances::default());
61+
debug!("SQLite plugin initialized");
6062
// Future PR: Possibly handle migrations here
61-
// Future PR: Cleanup on app exit
6263
Ok(())
6364
})
65+
.on_event(|app, event| {
66+
match event {
67+
RunEvent::ExitRequested { api, code, .. } => {
68+
info!("App exit requested (code: {:?}) - closing databases before exit", code);
69+
70+
// Prevent immediate exit so we can close connections and checkpoint WAL
71+
api.prevent_exit();
72+
73+
let instances = app.state::<DbInstances>();
74+
let app_handle = app.clone();
75+
76+
tokio::task::block_in_place(|| {
77+
tokio::runtime::Handle::current().block_on(async {
78+
let mut instances = instances.0.write().await;
79+
let wrappers: Vec<DatabaseWrapper> = instances.drain().map(|(_, v)| v).collect();
80+
81+
for wrapper in wrappers {
82+
if let Err(e) = wrapper.close().await {
83+
warn!("Error closing database during exit: {:?}", e);
84+
}
85+
}
86+
87+
debug!("All databases closed, calling exit()...");
88+
})
89+
});
90+
91+
app_handle.exit(code.unwrap_or(0));
92+
}
93+
RunEvent::Exit => {
94+
// ExitRequested should have already closed all databases
95+
// This is just a safety check
96+
let instances = app.state::<DbInstances>();
97+
if let Ok(instances) = instances.0.try_read() {
98+
if !instances.is_empty() {
99+
warn!("Exit event fired with {} database(s) still open - cleanup may have been skipped", instances.len());
100+
} else {
101+
debug!("Exit event: all databases already closed");
102+
}
103+
}
104+
}
105+
_ => {
106+
// Other events don't require action
107+
}
108+
}
109+
})
64110
.build()
65111
}
66112
}

0 commit comments

Comments
 (0)