feat(ffi): Add session_pool_max_size, …_cache_size and …_journal_size_limit.

This patch adds 3 methods on `ClientBuilder`:

1. `session_pool_max_size`,
2. `session_cache_size`,
3. `session_journal_size_limit`.

Respective fields are also added.

These values control the `SqliteStoreConfig`, used to control the
stores, especially their memory consumption.
This commit is contained in:
Ivan Enderlin
2025-04-01 09:00:23 +02:00
parent bb87a728ac
commit d7b6fae2a3
2 changed files with 73 additions and 8 deletions

View File

@@ -17,7 +17,7 @@ use matrix_sdk::{
VersionBuilderError,
},
Client as MatrixClient, ClientBuildError as MatrixClientBuildError, HttpError, IdParseError,
RumaApiError,
RumaApiError, SqliteStoreConfig,
};
use ruma::api::error::{DeserializationError, FromHttpResponseError};
use tracing::{debug, error};
@@ -256,6 +256,9 @@ impl From<ClientError> for ClientBuildError {
pub struct ClientBuilder {
session_paths: Option<SessionPaths>,
session_passphrase: Zeroizing<Option<String>>,
session_pool_max_size: Option<usize>,
session_cache_size: Option<u32>,
session_journal_size_limit: Option<u32>,
username: Option<String>,
homeserver_cfg: Option<HomeserverConfig>,
user_agent: Option<String>,
@@ -284,9 +287,12 @@ impl ClientBuilder {
pub fn new() -> Arc<Self> {
Arc::new(Self {
session_paths: None,
session_passphrase: Zeroizing::new(None),
session_pool_max_size: None,
session_cache_size: None,
session_journal_size_limit: None,
username: None,
homeserver_cfg: None,
session_passphrase: Zeroizing::new(None),
user_agent: None,
sliding_sync_version_builder: SlidingSyncVersionBuilder::None,
proxy: None,
@@ -371,6 +377,53 @@ impl ClientBuilder {
Arc::new(builder)
}
/// Set the pool max size for the SQLite stores given to
/// [`ClientBuilder::session_paths`].
///
/// Each store exposes an async pool of connections. This method controls
/// the size of the pool. The larger the pool is, the more memory is
/// consumed, but also the more the app is reactive because it doesn't need
/// to wait on a pool to be available to run queries.
///
/// See [`SqliteStoreConfig::pool_max_size`] to learn more.
pub fn session_pool_max_size(self: Arc<Self>, pool_max_size: Option<u32>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.session_pool_max_size = pool_max_size
.map(|size| size.try_into().expect("`pool_max_size` is too large to fit in `usize`"));
Arc::new(builder)
}
/// Set the cache size for the SQLite stores given to
/// [`ClientBuilder::session_paths`].
///
/// Each store exposes a SQLite connection. This method controls the cache
/// size, in **bytes (!)**.
///
/// The cache represents data SQLite holds in memory at once per open
/// database file. The default cache implementation does not allocate the
/// full amount of cache memory all at once. Cache memory is allocated
/// in smaller chunks on an as-needed basis.
///
/// See [`SqliteStoreConfig::cache_size`] to learn more.
pub fn session_cache_size(self: Arc<Self>, cache_size: Option<u32>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.session_cache_size = cache_size;
Arc::new(builder)
}
/// Set the size limit for the SQLite WAL files of stores given to
/// [`ClientBuilder::session_paths`].
///
/// Each store uses the WAL journal mode. This method controls the size
/// limit of the WAL files, in **bytes (!)**.
///
/// See [`SqliteStoreConfig::journal_size_limit`] to learn more.
pub fn session_journal_size_limit(self: Arc<Self>, limit: Option<u32>) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.session_journal_size_limit = limit;
Arc::new(builder)
}
pub fn username(self: Arc<Self>, username: String) -> Arc<Self> {
let mut builder = unwrap_or_clone_arc(self);
builder.username = Some(username);
@@ -523,11 +576,23 @@ impl ClientBuilder {
fs::create_dir_all(data_path)?;
fs::create_dir_all(cache_path)?;
inner_builder = inner_builder.sqlite_store_with_cache_path(
data_path,
cache_path,
builder.session_passphrase.as_deref(),
);
let mut sqlite_store_config =
SqliteStoreConfig::new(data_path).passphrase(builder.session_passphrase.as_deref());
if let Some(size) = builder.session_pool_max_size {
sqlite_store_config = sqlite_store_config.pool_max_size(size);
}
if let Some(size) = builder.session_cache_size {
sqlite_store_config = sqlite_store_config.cache_size(size);
}
if let Some(limit) = builder.session_journal_size_limit {
sqlite_store_config = sqlite_store_config.journal_size_limit(limit);
}
inner_builder = inner_builder
.sqlite_store_with_config_and_cache_path(sqlite_store_config, Some(cache_path));
} else {
debug!("Not using a store path.");
}

View File

@@ -76,7 +76,7 @@ pub use http_client::TransmissionProgress;
#[cfg(all(feature = "e2e-encryption", feature = "sqlite"))]
pub use matrix_sdk_sqlite::SqliteCryptoStore;
#[cfg(feature = "sqlite")]
pub use matrix_sdk_sqlite::{SqliteEventCacheStore, SqliteStateStore};
pub use matrix_sdk_sqlite::{SqliteEventCacheStore, SqliteStateStore, SqliteStoreConfig};
pub use media::Media;
pub use pusher::Pusher;
pub use room::Room;