Skip to content

Commit

Permalink
feat(storage): use a connection pool
Browse files Browse the repository at this point in the history
Instead of re-opening the Sqlite database for each request Storage now
contains a connection pool.
  • Loading branch information
kkovaacs committed Jun 7, 2022
1 parent 0474f6c commit 3b752c4
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 22 deletions.
32 changes: 32 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/pathfinder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ home = "0.5.3"
jsonrpsee = { version = "0.11.0", features = ["server"] }
lazy_static = "1.4.0"
num-bigint = { version = "0.4.3", features = ["serde"] }
r2d2 = "0.8.9"
r2d2_sqlite = "0.20.0"
reqwest = { version = "0.11.4", features = ["json"] }
rusqlite = { version = "0.27.0", features = ["bundled"] }
semver = "1.0.7"
Expand Down
37 changes: 15 additions & 22 deletions crates/pathfinder/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub use state::{
};

use anyhow::Context;
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use rusqlite::Connection;
use tracing::info;

Expand All @@ -31,6 +33,8 @@ const DB_VERSION_CURRENT: u32 = 10;
/// Sqlite key used for the PRAGMA user version.
const VERSION_KEY: &str = "user_version";

type PooledConnection = r2d2::PooledConnection<SqliteConnectionManager>;

/// Used to create [Connection's](Connection) to the pathfinder database.
///
/// Intended usage:
Expand All @@ -39,17 +43,12 @@ const VERSION_KEY: &str = "user_version";
/// - Use [Storage::connection] to create connection's to the database, which can in turn
/// be used to interact with the various [tables](self).
#[derive(Clone)]
pub struct Storage(std::sync::Arc<Inner>);
pub struct Storage(Inner);

#[derive(Clone)]
struct Inner {
database_path: PathBuf,
/// Required to keep the in-memory variant alive. Sqlite drops in-memory databases
/// as soon as all living connections are dropped, so we prevent this by storing
/// a keep-alive connection.
///
/// [Connection] is !Sync so we wrap it in [Mutex] to get sync back.
#[cfg(test)]
_keep_alive: Mutex<Connection>,
pool: Pool<SqliteConnectionManager>,
}

impl Storage {
Expand All @@ -60,31 +59,25 @@ impl Storage {
///
/// May be cloned safely.
pub fn migrate(database_path: PathBuf) -> anyhow::Result<Self> {
let mut conn = Self::open_connection(&database_path)?;
let manager = SqliteConnectionManager::file(&database_path);
let pool = Pool::builder().build(manager)?;

let mut conn = pool.get()?;
migrate_database(&mut conn).context("Migrate database")?;

#[cfg(not(test))]
let inner = Inner { database_path };
#[cfg(test)]
let inner = Inner {
database_path,
_keep_alive: Mutex::new(conn),
pool,
};

let storage = Storage(std::sync::Arc::new(inner));
let storage = Storage(inner);

Ok(storage)
}

/// Returns a new Sqlite [Connection] to the database.
pub fn connection(&self) -> anyhow::Result<Connection> {
Self::open_connection(&self.0.database_path)
}

/// Opens a connection the given database path.
fn open_connection(database_path: &Path) -> anyhow::Result<Connection> {
// TODO: think about flags?
let conn = Connection::open(database_path)?;
pub fn connection(&self) -> anyhow::Result<PooledConnection> {
let conn = self.0.pool.get()?;
Ok(conn)
}

Expand Down

0 comments on commit 3b752c4

Please sign in to comment.