mirror of
https://github.com/chatmail/core.git
synced 2026-05-09 01:46:30 +03:00
Introduce config caching
This commit is contained in:
38
src/sql.rs
38
src/sql.rs
@@ -3,7 +3,7 @@
|
|||||||
use async_std::path::Path;
|
use async_std::path::Path;
|
||||||
use async_std::sync::RwLock;
|
use async_std::sync::RwLock;
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@@ -39,12 +39,14 @@ mod migrations;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Sql {
|
pub struct Sql {
|
||||||
pool: RwLock<Option<r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>>>,
|
pool: RwLock<Option<r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>>>,
|
||||||
|
config_cache: RwLock<HashMap<String, String>>, // TODO should be <String, Option<String>> in order to save that an option is None?
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Sql {
|
impl Default for Sql {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
pool: RwLock::new(None),
|
pool: RwLock::new(None),
|
||||||
|
config_cache: RwLock::new(HashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -387,6 +389,8 @@ impl Sql {
|
|||||||
/// will already have been logged.
|
/// will already have been logged.
|
||||||
pub async fn set_raw_config(&self, key: impl AsRef<str>, value: Option<&str>) -> Result<()> {
|
pub async fn set_raw_config(&self, key: impl AsRef<str>, value: Option<&str>) -> Result<()> {
|
||||||
let key = key.as_ref();
|
let key = key.as_ref();
|
||||||
|
|
||||||
|
// TODO could be on another thread
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
let exists = self
|
let exists = self
|
||||||
.exists(
|
.exists(
|
||||||
@@ -413,20 +417,36 @@ impl Sql {
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut lock = self.config_cache.write().await;
|
||||||
|
if let Some(v) = value {
|
||||||
|
lock.insert(key.to_string(), v.to_string());
|
||||||
|
} else {
|
||||||
|
lock.remove(key);
|
||||||
|
}
|
||||||
|
drop(lock);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get configuration options from the database.
|
/// Get configuration options from the database.
|
||||||
pub async fn get_raw_config(&self, key: impl AsRef<str>) -> Result<Option<String>> {
|
pub async fn get_raw_config(&self, key: impl AsRef<str>) -> Result<Option<String>> {
|
||||||
let value = self
|
let lock = self.config_cache.read().await;
|
||||||
.query_get_value(
|
let cached = lock.get(key.as_ref()).cloned();
|
||||||
"SELECT value FROM config WHERE keyname=?;",
|
drop(lock);
|
||||||
paramsv![key.as_ref()],
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.context(format!("failed to fetch raw config: {}", key.as_ref()))?;
|
|
||||||
|
|
||||||
Ok(value)
|
if let Some(c) = cached {
|
||||||
|
Ok(Some(c))
|
||||||
|
} else {
|
||||||
|
let value = self
|
||||||
|
.query_get_value(
|
||||||
|
"SELECT value FROM config WHERE keyname=?;",
|
||||||
|
paramsv![key.as_ref()],
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.context(format!("failed to fetch raw config: {}", key.as_ref()))?;
|
||||||
|
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_raw_config_int(&self, key: impl AsRef<str>, value: i32) -> Result<()> {
|
pub async fn set_raw_config_int(&self, key: impl AsRef<str>, value: i32) -> Result<()> {
|
||||||
|
|||||||
@@ -526,6 +526,10 @@ impl Sql {
|
|||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let mut lock = self.config_cache.write().await;
|
||||||
|
lock.insert(VERSION_CFG.to_string(), format!("{}", version));
|
||||||
|
drop(lock);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user