Skip to content

Commit 63100d0

Browse files
committed
ledger: Add initial connection counter.
1 parent ac603c4 commit 63100d0

File tree

1 file changed

+63
-13
lines changed

1 file changed

+63
-13
lines changed

src/ledger/mod.rs

+63-13
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
//! immutable nature.
77
88
use crate::utils;
9-
use rusqlite::Connection;
9+
use rusqlite::{params, Connection};
1010
use std::{
1111
env,
12-
process::Command,
1312
sync::{Arc, Mutex},
1413
};
1514

@@ -44,24 +43,16 @@ impl Ledger {
4443
let path = Ledger::get_database_path(path);
4544
let _ = utils::initialize_logger();
4645

47-
// Check if database has another connections.
48-
let is_open = {
49-
let ret = Command::new("lsof")
50-
.args([&path])
51-
.output()
52-
.expect("failed to execute process");
53-
54-
!ret.stdout.is_empty()
55-
};
56-
5746
let database = Connection::open(path.clone()).unwrap();
5847

5948
// If database has another connections, skip clearing.
60-
if !is_open {
49+
if Ledger::get_database_connection_count(&database) == 0 {
6150
tracing::trace!("Creating new database at path {path}");
51+
6252
Ledger::drop_tables(&database).unwrap();
6353
Ledger::create_tables(&database).unwrap();
6454
}
55+
Ledger::increment_connection_count(&database);
6556

6657
tracing::trace!("Database connection to {path} is established");
6758

@@ -95,13 +86,51 @@ impl Ledger {
9586
}
9687
}
9788

89+
/// Returns current connection count to the database. If not zero
90+
fn get_database_connection_count(database: &Connection) -> i64 {
91+
let count = database.query_row("SELECT count FROM connection_info", params![], |row| {
92+
Ok(row.get::<_, i64>(0).unwrap())
93+
});
94+
95+
let count = match count {
96+
Ok(count) => count,
97+
Err(_) => 0,
98+
};
99+
tracing::trace!("Current connection count: {count}");
100+
101+
count
102+
}
103+
104+
/// Increments connection count.
105+
fn increment_connection_count(database: &Connection) {
106+
let count = Self::get_database_connection_count(database) + 1;
107+
tracing::trace!("Incrementing connection count to {count}...");
108+
109+
database
110+
.execute("UPDATE connection_info SET count = ?1", params![count])
111+
.unwrap();
112+
}
113+
114+
/// Decrements connection count.
115+
fn decrement_connection_count(&self) {
116+
let count = Self::get_database_connection_count(&self.database.lock().unwrap()) - 1;
117+
tracing::trace!("Decrementing connection count to {count}...");
118+
119+
self.database
120+
.lock()
121+
.unwrap()
122+
.execute("UPDATE connection_info SET count = ?1", params![count])
123+
.unwrap();
124+
}
125+
98126
fn get_database_path(path: &str) -> String {
99127
env::temp_dir().to_str().unwrap().to_owned() + "/bitcoin_mock_rpc_" + path
100128
}
101129

102130
fn drop_tables(database: &Connection) -> Result<(), rusqlite::Error> {
103131
database.execute_batch(
104132
"
133+
DROP TABLE IF EXISTS connection_info;
105134
DROP TABLE IF EXISTS blocks;
106135
DROP TABLE IF EXISTS mempool;
107136
DROP TABLE IF EXISTS transactions;
@@ -117,6 +146,14 @@ impl Ledger {
117146
fn create_tables(database: &Connection) -> Result<(), rusqlite::Error> {
118147
database.execute_batch(
119148
"
149+
CREATE TABLE connection_info
150+
(
151+
count INTEGER NOT NULL
152+
153+
CONSTRAINT count PRIMARY KEY
154+
);
155+
INSERT INTO connection_info (count) VALUES (0);
156+
120157
CREATE TABLE blocks
121158
(
122159
height INTEGER NOT NULL,
@@ -155,6 +192,12 @@ impl Ledger {
155192
}
156193
}
157194

195+
impl Drop for Ledger {
196+
fn drop(&mut self) {
197+
self.decrement_connection_count();
198+
}
199+
}
200+
158201
#[cfg(test)]
159202
mod tests {
160203
use super::*;
@@ -163,4 +206,11 @@ mod tests {
163206
fn new() {
164207
let _should_not_panic = Ledger::new("ledger_new");
165208
}
209+
210+
#[test]
211+
fn concurrent_connections() {
212+
let _ledger = Ledger::new("concurrent_connections");
213+
214+
let _ledger2 = Ledger::new("concurrent_connections");
215+
}
166216
}

0 commit comments

Comments
 (0)