Skip to content

Commit ab60545

Browse files
committed
refactor: refactored persistent torrent loading/saving
1 parent b34f564 commit ab60545

File tree

3 files changed

+56
-57
lines changed

3 files changed

+56
-57
lines changed

src/database.rs

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use crate::{InfoHash, AUTH_KEY_LENGTH, TorrentTracker};
1+
use std::collections::BTreeMap;
2+
use crate::{InfoHash, AUTH_KEY_LENGTH, TorrentEntry};
23
use log::debug;
34
use r2d2_sqlite::{SqliteConnectionManager, rusqlite};
45
use r2d2::{Pool};
56
use r2d2_sqlite::rusqlite::NO_PARAMS;
67
use crate::key_manager::AuthKey;
78
use std::str::FromStr;
8-
use std::sync::Arc;
99

1010
pub struct SqliteDatabase {
1111
pool: Pool<SqliteConnectionManager>
@@ -73,40 +73,34 @@ impl SqliteDatabase {
7373
}
7474
}
7575

76-
pub async fn load_persistent_torrent_data(&self, tracker: Arc<TorrentTracker>) -> Result<bool, rusqlite::Error> {
77-
let tracker_copy = tracker.clone();
76+
pub async fn load_persistent_torrent_data(&self) -> Result<Vec<(InfoHash, u32)>, rusqlite::Error> {
7877
let conn = self.pool.get().unwrap();
7978
let mut stmt = conn.prepare("SELECT info_hash, completed FROM torrents")?;
8079

81-
let info_hash_iter = stmt.query_map(NO_PARAMS, |row| {
82-
let info_hash: String = row.get(0)?;
83-
let info_hash_converted = InfoHash::from_str(&info_hash).unwrap();
80+
let torrent_iter = stmt.query_map(NO_PARAMS, |row| {
81+
let info_hash_string: String = row.get(0)?;
82+
let info_hash = InfoHash::from_str(&info_hash_string).unwrap();
8483
let completed: u32 = row.get(1)?;
85-
Ok((info_hash_converted, completed))
84+
Ok((info_hash, completed))
8685
})?;
8786

88-
for info_hash_item in info_hash_iter {
89-
let (info_hash, completed): (InfoHash, u32) = info_hash_item.unwrap();
90-
tracker_copy.add_torrent(&info_hash, 0u32, completed, 0u32).await;
91-
}
87+
let torrents: Vec<(InfoHash, u32)> = torrent_iter.filter_map(|x| x.ok() ).collect();
9288

93-
Ok(true)
89+
Ok(torrents)
9490
}
9591

96-
pub async fn save_persistent_torrent_data(&self, tracker: Arc<TorrentTracker>) -> Result<bool, rusqlite::Error> {
97-
let tracker_copy = tracker.clone();
92+
pub async fn save_persistent_torrent_data(&self, torrents: &BTreeMap<InfoHash, TorrentEntry>) -> Result<(), rusqlite::Error> {
9893
let mut conn = self.pool.get().unwrap();
99-
let db = tracker_copy.get_torrents().await;
10094
let db_transaction = conn.transaction()?;
101-
let _: Vec<_> = db
102-
.iter()
103-
.map(|(info_hash, torrent_entry)| {
95+
96+
for (info_hash, torrent_entry) in torrents {
10497
let (_seeders, completed, _leechers) = torrent_entry.get_stats();
10598
let _ = db_transaction.execute("INSERT OR REPLACE INTO torrents (info_hash, completed) VALUES (?, ?)", &[info_hash.to_string(), completed.to_string()]);
106-
})
107-
.collect();
99+
}
100+
108101
let _ = db_transaction.commit();
109-
Ok(true)
102+
103+
Ok(())
110104
}
111105

112106
pub async fn get_info_hash_from_whitelist(&self, info_hash: &str) -> Result<InfoHash, rusqlite::Error> {

src/main.rs

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@ async fn main() {
1717
logging::setup_logging(&config);
1818

1919
// the singleton torrent tracker that gets passed to the HTTP and UDP server
20-
let tracker = Arc::new(TorrentTracker::new(config.clone()));
20+
let tracker = Arc::new(TorrentTracker::new(config.clone()).unwrap_or_else(|e| {
21+
panic!("{}", e)
22+
}));
2123

22-
// Load torrents if enabled
24+
// load persistent torrents if enabled
2325
if config.persistence {
24-
load_torrents_into_memory(tracker.clone()).await;
26+
info!("Loading persistent torrents into memory...");
27+
if tracker.load_torrents().await.is_err() {
28+
panic!("Could not load persistent torrents.")
29+
};
30+
info!("Persistent torrents loaded.");
2531
}
2632

2733
// start torrent cleanup job (periodically removes old peers)
@@ -48,27 +54,18 @@ async fn main() {
4854
// handle the signals here
4955
let ctrl_c = tokio::signal::ctrl_c();
5056
tokio::select! {
51-
_ = ctrl_c => { info!("Torrust shutting down..") }
52-
}
53-
54-
// Save torrents if enabled
55-
if config.persistence {
56-
save_torrents_into_memory(tracker.clone()).await;
57+
_ = ctrl_c => {
58+
info!("Torrust shutting down..");
59+
// Save torrents if enabled
60+
if config.persistence {
61+
info!("Saving torrents into SQL from memory...");
62+
let _ = tracker.save_torrents().await;
63+
info!("Torrents saved");
64+
}
65+
}
5766
}
5867
}
5968

60-
async fn load_torrents_into_memory(tracker: Arc<TorrentTracker>) {
61-
info!("Loading torrents from SQL into memory...");
62-
let _ = tracker.load_torrents(tracker.clone()).await;
63-
info!("Torrents loaded");
64-
}
65-
66-
async fn save_torrents_into_memory(tracker: Arc<TorrentTracker>) {
67-
info!("Saving torrents into SQL from memory...");
68-
let _ = tracker.save_torrents(tracker.clone()).await;
69-
info!("Torrents saved");
70-
}
71-
7269
fn start_torrent_cleanup_job(config: Arc<Configuration>, tracker: Arc<TorrentTracker>) -> Option<JoinHandle<()>> {
7370
let weak_tracker = std::sync::Arc::downgrade(&tracker);
7471
let interval = config.cleanup_interval.unwrap_or(600);

src/tracker.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::collections::btree_map::Entry;
1010
use crate::database::SqliteDatabase;
1111
use std::sync::Arc;
1212
use aquatic_udp_protocol::{AnnounceEvent, NumberOfBytes};
13-
use log::debug;
13+
use log::{debug};
1414
use crate::key_manager::AuthKey;
1515
use r2d2_sqlite::rusqlite;
1616
use crate::torrust_http_tracker::AnnounceRequest;
@@ -270,12 +270,10 @@ pub struct TorrentTracker {
270270
}
271271

272272
impl TorrentTracker {
273-
pub fn new(config: Arc<Configuration>) -> TorrentTracker {
274-
let database = SqliteDatabase::new(&config.db_path).unwrap_or_else(|error| {
275-
panic!("Could not create SQLite database. Reason: {}", error)
276-
});
273+
pub fn new(config: Arc<Configuration>) -> Result<TorrentTracker, rusqlite::Error> {
274+
let database = SqliteDatabase::new(&config.db_path)?;
277275

278-
TorrentTracker {
276+
Ok(TorrentTracker {
279277
config,
280278
torrents: RwLock::new(std::collections::BTreeMap::new()),
281279
database,
@@ -293,7 +291,7 @@ impl TorrentTracker {
293291
udp6_announces_handled: 0,
294292
udp6_scrapes_handled: 0,
295293
}),
296-
}
294+
})
297295
}
298296

299297
fn is_public(&self) -> bool {
@@ -355,13 +353,20 @@ impl TorrentTracker {
355353
}
356354

357355
// Loading the torrents into memory
358-
pub async fn load_torrents(&self, tracker: Arc<TorrentTracker>) -> Result<bool, rusqlite::Error> {
359-
self.database.load_persistent_torrent_data(tracker).await
356+
pub async fn load_torrents(&self) -> Result<(), rusqlite::Error> {
357+
let torrents = self.database.load_persistent_torrent_data().await?;
358+
359+
for torrent in torrents {
360+
self.add_torrent(torrent.0, 0, torrent.1, 0).await;
361+
}
362+
363+
Ok(())
360364
}
361365

362366
// Saving the torrents from memory
363-
pub async fn save_torrents(&self, tracker: Arc<TorrentTracker>) -> Result<bool, rusqlite::Error> {
364-
self.database.save_persistent_torrent_data(tracker).await
367+
pub async fn save_torrents(&self) -> Result<(), rusqlite::Error> {
368+
let torrents = self.torrents.read().await;
369+
self.database.save_persistent_torrent_data(&*torrents).await
365370
}
366371

367372
// Adding torrents is not relevant to public trackers.
@@ -419,12 +424,15 @@ impl TorrentTracker {
419424
}
420425
}
421426

422-
pub async fn add_torrent(&self, info_hash: &InfoHash, seeders: u32, completed: u32, leechers: u32) -> TorrentStats {
427+
pub async fn add_torrent(&self, info_hash: InfoHash, seeders: u32, completed: u32, leechers: u32) -> TorrentStats {
423428
let mut torrents = self.torrents.write().await;
424429

425430
if !torrents.contains_key(&info_hash) {
426-
let mut torrent_entry = TorrentEntry::new();
427-
torrent_entry.completed = completed;
431+
let torrent_entry = TorrentEntry {
432+
peers: Default::default(),
433+
completed,
434+
seeders
435+
};
428436
torrents.insert(info_hash.clone(), torrent_entry);
429437
}
430438

0 commit comments

Comments
 (0)