fix: set SQLite busy timeout to 1 minute on iOS

Closes <https://github.com/chatmail/core/issues/7464>
This commit is contained in:
link2xt
2025-11-18 14:54:54 +00:00
committed by l
parent 72788daca0
commit abfb556377

View File

@@ -2,6 +2,7 @@
use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::time::Duration;
use anyhow::{Context as _, Result, bail, ensure};
use rusqlite::{Connection, OpenFlags, Row, config::DbConfig, types::ValueRef};
@@ -760,7 +761,6 @@ fn new_connection(path: &Path, passphrase: &str) -> Result<Connection> {
conn.execute_batch(
"PRAGMA cipher_memory_security = OFF; -- Too slow on Android
PRAGMA secure_delete=on;
PRAGMA busy_timeout = 0; -- fail immediately
PRAGMA soft_heap_limit = 8388608; -- 8 MiB limit, same as set in Android SQLiteDatabase.
PRAGMA foreign_keys=on;
",
@@ -773,6 +773,22 @@ fn new_connection(path: &Path, passphrase: &str) -> Result<Connection> {
conn.pragma_update(None, "temp_store", "memory")?;
}
// Fail immediately when the database is busy,
// except for iOS. On iOS we don't have
// `accounts.lock` lockfile and the database
// is used by two processes:
// main process and the notification extension.
// Due to a bug they both may run at the same time
// and try to write to the database.
// As a workaround, we wait up to 1 minute and retry
// instead of failing immediately and
// possibly missing a message.
if cfg!(target_os = "ios") {
conn.busy_timeout(Duration::new(60, 0))?;
} else {
conn.busy_timeout(Duration::ZERO)?;
}
if !passphrase.is_empty() {
conn.pragma_update(None, "key", passphrase)?;
}