node: Allow for "WAL" mode in sqlite

This solves concurrency issues between the node and http daemon.
This commit is contained in:
cloudhead 2024-05-14 16:34:30 +02:00
parent 25c6660a59
commit 21cced05c1
No known key found for this signature in database
5 changed files with 44 additions and 2 deletions

View File

@ -26,6 +26,9 @@ $ rad config
},
"connect": [],
"externalAddresses": [],
"db": {
"journalMode": "rollback"
},
"tor": null,
"network": "main",
"log": "INFO",

View File

@ -89,6 +89,7 @@ mod routes {
},
"connect": [],
"externalAddresses": [],
"db": { "journalMode": "rollback" },
"tor": null,
"network": "main",
"log": "INFO",

View File

@ -156,7 +156,7 @@ impl Runtime {
let policy = config.policy;
log::info!(target: "node", "Opening node database..");
let db = home.database_mut()?;
let db = home.database_mut()?.journal_mode(config.db.journal_mode)?;
let mut stores: service::Stores<_> = db.clone().into();
log::info!(target: "node", "Opening policy database..");

View File

@ -7,7 +7,7 @@ use localtime::LocalDuration;
use crate::node;
use crate::node::policy::{Policy, Scope};
use crate::node::{Address, Alias, NodeId};
use crate::node::{db, Address, Alias, NodeId};
/// Target number of peers to maintain connections to.
pub const TARGET_OUTBOUND_PEERS: usize = 8;
@ -260,6 +260,14 @@ pub enum TorConfig {
Transparent,
}
/// Database configuration.
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DbConfig {
#[serde(default)]
pub journal_mode: db::JournalMode,
}
/// Service configuration.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
@ -279,6 +287,9 @@ pub struct Config {
/// Specify the node's public addresses
#[serde(default)]
pub external_addresses: Vec<Address>,
/// Database config.
#[serde(default)]
pub db: DbConfig,
/// Tor configuration.
#[serde(default)]
pub tor: Option<TorConfig>,
@ -321,6 +332,7 @@ impl Config {
listen: vec![],
connect: HashSet::default(),
external_addresses: vec![],
db: DbConfig::default(),
network: Network::default(),
tor: None,
relay: Relay::default(),

View File

@ -40,6 +40,19 @@ pub enum Error {
NoRows,
}
/// Database journal mode.
#[derive(Debug, Default, Copy, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum JournalMode {
/// "WAL" mode. Good for concurrent reads & writes, but keeps some extra files around.
#[serde(rename = "wal")]
WriteAheadLog,
/// Default "rollback" mode. Certain writes may block reads.
#[serde(alias = "rollback")]
#[default]
Rollback,
}
/// A file-backed database storing information about the network.
#[derive(Clone)]
pub struct Database {
@ -93,6 +106,19 @@ impl Database {
Ok(Self { db: Arc::new(db) })
}
/// Set journal mode.
pub fn journal_mode(self, mode: JournalMode) -> Result<Self, Error> {
match mode {
JournalMode::Rollback => {
self.db.execute("PRAGMA journal_mode = DELETE;")?;
}
JournalMode::WriteAheadLog => {
self.db.execute("PRAGMA journal_mode = WAL;")?;
}
}
Ok(self)
}
/// Create a new in-memory database.
pub fn memory() -> Result<Self, Error> {
let db = sql::Connection::open_thread_safe(":memory:")?;