From 03ef7f6178ae9c25f4fca925741c9d48bf809886 Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 16:23:28 +0000
Subject: [PATCH 01/11] refactor: [1201] extract InMemoryTorrentRepository

---
 src/core/mod.rs                          |  33 +++-----
 src/core/services/torrent.rs             |   1 -
 src/core/torrent/mod.rs                  |   2 +
 src/core/torrent/repository/in_memory.rs | 103 +++++++++++++++++++++++
 src/core/torrent/repository/mod.rs       |   1 +
 5 files changed, 116 insertions(+), 24 deletions(-)
 create mode 100644 src/core/torrent/repository/in_memory.rs
 create mode 100644 src/core/torrent/repository/mod.rs

diff --git a/src/core/mod.rs b/src/core/mod.rs
index 26ef69bfa..fd25a0506 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -449,22 +449,19 @@ pub mod whitelist;
 
 pub mod peer_tests;
 
-use std::cmp::max;
 use std::net::IpAddr;
 use std::sync::Arc;
 use std::time::Duration;
 
 use bittorrent_primitives::info_hash::InfoHash;
+use torrent::repository::in_memory::InMemoryTorrentRepository;
 use torrust_tracker_clock::clock::Time;
 use torrust_tracker_configuration::{AnnouncePolicy, Core, TORRENT_PEERS_LIMIT};
 use torrust_tracker_primitives::core::{AnnounceData, ScrapeData};
 use torrust_tracker_primitives::peer;
 use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
 use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
-use torrust_tracker_torrent_repository::entry::EntrySync;
-use torrust_tracker_torrent_repository::repository::Repository;
 
-use self::torrent::Torrents;
 use crate::core::databases::Database;
 use crate::CurrentClock;
 
@@ -489,7 +486,7 @@ pub struct Tracker {
     pub whitelist_authorization: Arc<whitelist::authorization::Authorization>,
 
     /// The in-memory torrents repository.
-    torrents: Arc<Torrents>,
+    torrents: Arc<InMemoryTorrentRepository>,
 }
 
 /// How many peers the peer announcing wants in the announce response.
@@ -549,7 +546,7 @@ impl Tracker {
             config: config.clone(),
             database: database.clone(),
             whitelist_authorization: whitelist_authorization.clone(),
-            torrents: Arc::default(),
+            torrents: Arc::new(InMemoryTorrentRepository::default()),
         })
     }
 
@@ -656,10 +653,7 @@ impl Tracker {
 
     /// It returns the data for a `scrape` response.
     fn get_swarm_metadata(&self, info_hash: &InfoHash) -> SwarmMetadata {
-        match self.torrents.get(info_hash) {
-            Some(torrent_entry) => torrent_entry.get_swarm_metadata(),
-            None => SwarmMetadata::default(),
-        }
+        self.torrents.get_swarm_metadata(info_hash)
     }
 
     /// It loads the torrents from database into memory. It only loads the torrent entry list with the number of seeders for each torrent.
@@ -684,10 +678,7 @@ impl Tracker {
     ///
     /// It filters out the client making the request.
     fn get_peers_for(&self, info_hash: &InfoHash, peer: &peer::Peer, limit: usize) -> Vec<Arc<peer::Peer>> {
-        match self.torrents.get(info_hash) {
-            None => vec![],
-            Some(entry) => entry.get_peers_for_client(&peer.peer_addr, Some(max(limit, TORRENT_PEERS_LIMIT))),
-        }
+        self.torrents.get_peers_for(info_hash, peer, limit)
     }
 
     /// # Context: Tracker
@@ -695,10 +686,7 @@ impl Tracker {
     /// Get torrent peers for a given torrent.
     #[must_use]
     pub fn get_torrent_peers(&self, info_hash: &InfoHash) -> Vec<Arc<peer::Peer>> {
-        match self.torrents.get(info_hash) {
-            None => vec![],
-            Some(entry) => entry.get_peers(Some(TORRENT_PEERS_LIMIT)),
-        }
+        self.torrents.get_torrent_peers(info_hash)
     }
 
     /// It updates the torrent entry in memory, it also stores in the database
@@ -708,14 +696,14 @@ impl Tracker {
     /// # Context: Tracker
     #[must_use]
     pub fn upsert_peer_and_get_stats(&self, info_hash: &InfoHash, peer: &peer::Peer) -> SwarmMetadata {
-        let swarm_metadata_before = match self.torrents.get_swarm_metadata(info_hash) {
+        let swarm_metadata_before = match self.torrents.get_opt_swarm_metadata(info_hash) {
             Some(swarm_metadata) => swarm_metadata,
             None => SwarmMetadata::zeroed(),
         };
 
         self.torrents.upsert_peer(info_hash, peer);
 
-        let swarm_metadata_after = match self.torrents.get_swarm_metadata(info_hash) {
+        let swarm_metadata_after = match self.torrents.get_opt_swarm_metadata(info_hash) {
             Some(swarm_metadata) => swarm_metadata,
             None => SwarmMetadata::zeroed(),
         };
@@ -748,7 +736,7 @@ impl Tracker {
     /// Panics if unable to get the torrent metrics.
     #[must_use]
     pub fn get_torrents_metrics(&self) -> TorrentsMetrics {
-        self.torrents.get_metrics()
+        self.torrents.get_torrents_metrics()
     }
 
     /// Remove inactive peers and (optionally) peerless torrents.
@@ -1492,7 +1480,6 @@ mod tests {
 
             use aquatic_udp_protocol::AnnounceEvent;
             use torrust_tracker_torrent_repository::entry::EntrySync;
-            use torrust_tracker_torrent_repository::repository::Repository;
 
             use crate::core::tests::the_tracker::{sample_info_hash, sample_peer, tracker_persisting_torrents_in_database};
 
@@ -1513,7 +1500,7 @@ mod tests {
                 assert_eq!(swarm_stats.downloaded, 1);
 
                 // Remove the newly updated torrent from memory
-                tracker.torrents.remove(&info_hash);
+                let _unused = tracker.torrents.remove(&info_hash);
 
                 tracker.load_torrents_from_database().unwrap();
 
diff --git a/src/core/services/torrent.rs b/src/core/services/torrent.rs
index 9b7254098..7f99451eb 100644
--- a/src/core/services/torrent.rs
+++ b/src/core/services/torrent.rs
@@ -10,7 +10,6 @@ use bittorrent_primitives::info_hash::InfoHash;
 use torrust_tracker_primitives::pagination::Pagination;
 use torrust_tracker_primitives::peer;
 use torrust_tracker_torrent_repository::entry::EntrySync;
-use torrust_tracker_torrent_repository::repository::Repository;
 
 use crate::core::Tracker;
 
diff --git a/src/core/torrent/mod.rs b/src/core/torrent/mod.rs
index 38311864b..3e3e065f2 100644
--- a/src/core/torrent/mod.rs
+++ b/src/core/torrent/mod.rs
@@ -25,6 +25,8 @@
 //! - The number of peers that have NOT completed downloading the torrent and are still active, that means they are actively participating in the network.
 //!   Peer that don not have a full copy of the torrent data are called "leechers".
 //!
+pub mod repository;
+
 use torrust_tracker_torrent_repository::TorrentsSkipMapMutexStd;
 
 pub type Torrents = TorrentsSkipMapMutexStd; // Currently Used
diff --git a/src/core/torrent/repository/in_memory.rs b/src/core/torrent/repository/in_memory.rs
new file mode 100644
index 000000000..6b1902d95
--- /dev/null
+++ b/src/core/torrent/repository/in_memory.rs
@@ -0,0 +1,103 @@
+use std::cmp::max;
+use std::sync::Arc;
+
+use bittorrent_primitives::info_hash::InfoHash;
+use torrust_tracker_configuration::{TrackerPolicy, TORRENT_PEERS_LIMIT};
+use torrust_tracker_primitives::pagination::Pagination;
+use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
+use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
+use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
+use torrust_tracker_torrent_repository::entry::EntrySync;
+use torrust_tracker_torrent_repository::repository::Repository;
+use torrust_tracker_torrent_repository::EntryMutexStd;
+
+use crate::core::torrent::Torrents;
+
+/// The in-memory torrents repository.
+///
+/// There are many implementations of the repository trait. We tried with
+/// different types of data structures, but the best performance was with
+/// the one we use for production. We kept the other implementations for
+/// reference.
+#[derive(Debug, Default)]
+pub struct InMemoryTorrentRepository {
+    /// The in-memory torrents repository implementation.
+    torrents: Arc<Torrents>,
+}
+
+impl InMemoryTorrentRepository {
+    /// It inserts (or updates if it's already in the list) the peer in the
+    /// torrent entry.
+    pub fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) {
+        self.torrents.upsert_peer(info_hash, peer);
+    }
+
+    #[must_use]
+    pub fn remove(&self, key: &InfoHash) -> Option<EntryMutexStd> {
+        self.torrents.remove(key)
+    }
+
+    pub fn remove_inactive_peers(&self, current_cutoff: DurationSinceUnixEpoch) {
+        self.torrents.remove_inactive_peers(current_cutoff);
+    }
+
+    pub fn remove_peerless_torrents(&self, policy: &TrackerPolicy) {
+        self.torrents.remove_peerless_torrents(policy);
+    }
+
+    #[must_use]
+    pub fn get(&self, key: &InfoHash) -> Option<EntryMutexStd> {
+        self.torrents.get(key)
+    }
+
+    #[must_use]
+    pub fn get_paginated(&self, pagination: Option<&Pagination>) -> Vec<(InfoHash, EntryMutexStd)> {
+        self.torrents.get_paginated(pagination)
+    }
+
+    /// It returns the data for a `scrape` response or empty if the torrent is
+    /// not found.
+    #[must_use]
+    pub fn get_swarm_metadata(&self, info_hash: &InfoHash) -> SwarmMetadata {
+        match self.torrents.get(info_hash) {
+            Some(torrent_entry) => torrent_entry.get_swarm_metadata(),
+            None => SwarmMetadata::default(),
+        }
+    }
+
+    /// It returns the data for a `scrape` response if the torrent is found.
+    #[must_use]
+    pub fn get_opt_swarm_metadata(&self, info_hash: &InfoHash) -> Option<SwarmMetadata> {
+        self.torrents.get_swarm_metadata(info_hash)
+    }
+
+    /// Get torrent peers for a given torrent and client.
+    ///
+    /// It filters out the client making the request.
+    #[must_use]
+    pub fn get_peers_for(&self, info_hash: &InfoHash, peer: &peer::Peer, limit: usize) -> Vec<Arc<peer::Peer>> {
+        match self.torrents.get(info_hash) {
+            None => vec![],
+            Some(entry) => entry.get_peers_for_client(&peer.peer_addr, Some(max(limit, TORRENT_PEERS_LIMIT))),
+        }
+    }
+
+    /// Get torrent peers for a given torrent.
+    #[must_use]
+    pub fn get_torrent_peers(&self, info_hash: &InfoHash) -> Vec<Arc<peer::Peer>> {
+        match self.torrents.get(info_hash) {
+            None => vec![],
+            Some(entry) => entry.get_peers(Some(TORRENT_PEERS_LIMIT)),
+        }
+    }
+
+    /// It calculates and returns the general [`TorrentsMetrics`].
+    #[must_use]
+    pub fn get_torrents_metrics(&self) -> TorrentsMetrics {
+        self.torrents.get_metrics()
+    }
+
+    pub fn import_persistent(&self, persistent_torrents: &PersistentTorrents) {
+        self.torrents.import_persistent(persistent_torrents);
+    }
+}
diff --git a/src/core/torrent/repository/mod.rs b/src/core/torrent/repository/mod.rs
new file mode 100644
index 000000000..fa2e12699
--- /dev/null
+++ b/src/core/torrent/repository/mod.rs
@@ -0,0 +1 @@
+pub mod in_memory;

From 9b5f776c28483e17d5dfa39f4026faacf7aa6546 Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 16:50:56 +0000
Subject: [PATCH 02/11] refactor: [#1201] exatrct
 DatabasePersistentTorrentRepository

---
 src/core/mod.rs                          | 11 ++++--
 src/core/torrent/repository/mod.rs       |  1 +
 src/core/torrent/repository/persisted.rs | 44 ++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 3 deletions(-)
 create mode 100644 src/core/torrent/repository/persisted.rs

diff --git a/src/core/mod.rs b/src/core/mod.rs
index fd25a0506..4cb4a04ef 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -455,6 +455,7 @@ use std::time::Duration;
 
 use bittorrent_primitives::info_hash::InfoHash;
 use torrent::repository::in_memory::InMemoryTorrentRepository;
+use torrent::repository::persisted::DatabasePersistentTorrentRepository;
 use torrust_tracker_clock::clock::Time;
 use torrust_tracker_configuration::{AnnouncePolicy, Core, TORRENT_PEERS_LIMIT};
 use torrust_tracker_primitives::core::{AnnounceData, ScrapeData};
@@ -487,6 +488,9 @@ pub struct Tracker {
 
     /// The in-memory torrents repository.
     torrents: Arc<InMemoryTorrentRepository>,
+
+    /// The persistent torrents repository.
+    db_torrent_repository: Arc<DatabasePersistentTorrentRepository>,
 }
 
 /// How many peers the peer announcing wants in the announce response.
@@ -547,6 +551,7 @@ impl Tracker {
             database: database.clone(),
             whitelist_authorization: whitelist_authorization.clone(),
             torrents: Arc::new(InMemoryTorrentRepository::default()),
+            db_torrent_repository: Arc::new(DatabasePersistentTorrentRepository::new(database)),
         })
     }
 
@@ -665,7 +670,7 @@ impl Tracker {
     ///
     /// Will return a `database::Error` if unable to load the list of `persistent_torrents` from the database.
     pub fn load_torrents_from_database(&self) -> Result<(), databases::error::Error> {
-        let persistent_torrents = self.database.load_persistent_torrents()?;
+        let persistent_torrents = self.db_torrent_repository.load_all()?;
 
         self.torrents.import_persistent(&persistent_torrents);
 
@@ -723,7 +728,7 @@ impl Tracker {
             let completed = swarm_metadata.downloaded;
             let info_hash = *info_hash;
 
-            drop(self.database.save_persistent_torrent(&info_hash, completed));
+            drop(self.db_torrent_repository.save(&info_hash, completed));
         }
     }
 
@@ -759,7 +764,7 @@ impl Tracker {
     ///
     /// Will return `Err` if unable to drop tables.
     pub fn drop_database_tables(&self) -> Result<(), databases::error::Error> {
-        // todo: this is only used for testing. WE have to pass the database
+        // todo: this is only used for testing. We have to pass the database
         // reference directly to the tests instead of via the tracker.
         self.database.drop_database_tables()
     }
diff --git a/src/core/torrent/repository/mod.rs b/src/core/torrent/repository/mod.rs
index fa2e12699..51723b68d 100644
--- a/src/core/torrent/repository/mod.rs
+++ b/src/core/torrent/repository/mod.rs
@@ -1 +1,2 @@
 pub mod in_memory;
+pub mod persisted;
diff --git a/src/core/torrent/repository/persisted.rs b/src/core/torrent/repository/persisted.rs
new file mode 100644
index 000000000..86a3db0e3
--- /dev/null
+++ b/src/core/torrent/repository/persisted.rs
@@ -0,0 +1,44 @@
+use std::sync::Arc;
+
+use bittorrent_primitives::info_hash::InfoHash;
+use torrust_tracker_primitives::PersistentTorrents;
+
+use crate::core::databases::error::Error;
+use crate::core::databases::Database;
+
+/// Torrent repository implementation that persists the torrents in a database.
+///
+/// Not all the torrent in-memory data is persisted. For now only some of the
+/// torrent metrics are persisted.
+pub struct DatabasePersistentTorrentRepository {
+    /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite)
+    /// or [`MySQL`](crate::core::databases::mysql)
+    database: Arc<Box<dyn Database>>,
+}
+
+impl DatabasePersistentTorrentRepository {
+    #[must_use]
+    pub fn new(database: &Arc<Box<dyn Database>>) -> DatabasePersistentTorrentRepository {
+        Self {
+            database: database.clone(),
+        }
+    }
+
+    /// It loads the persistent torrents from the database.
+    ///
+    /// # Errors
+    ///
+    /// Will return a database `Err` if unable to load.
+    pub fn load_all(&self) -> Result<PersistentTorrents, Error> {
+        self.database.load_persistent_torrents()
+    }
+
+    /// It saves the persistent torrent into the database.
+    ///
+    /// # Errors
+    ///
+    /// Will return a database `Err` if unable to save.
+    pub fn save(&self, info_hash: &InfoHash, downloaded: u32) -> Result<(), Error> {
+        self.database.save_persistent_torrent(info_hash, downloaded)
+    }
+}

From f4dcb51f1f5eaa6e2a34c441d2b4d816807f56bd Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 16:52:55 +0000
Subject: [PATCH 03/11] refactor: [#1201] rename tracker field

---
 src/core/mod.rs              | 32 ++++++++++++++++++--------------
 src/core/services/torrent.rs | 10 +++++++---
 2 files changed, 25 insertions(+), 17 deletions(-)

diff --git a/src/core/mod.rs b/src/core/mod.rs
index 4cb4a04ef..c9a7e9dc3 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -487,7 +487,7 @@ pub struct Tracker {
     pub whitelist_authorization: Arc<whitelist::authorization::Authorization>,
 
     /// The in-memory torrents repository.
-    torrents: Arc<InMemoryTorrentRepository>,
+    in_memory_torrent_repository: Arc<InMemoryTorrentRepository>,
 
     /// The persistent torrents repository.
     db_torrent_repository: Arc<DatabasePersistentTorrentRepository>,
@@ -550,7 +550,7 @@ impl Tracker {
             config: config.clone(),
             database: database.clone(),
             whitelist_authorization: whitelist_authorization.clone(),
-            torrents: Arc::new(InMemoryTorrentRepository::default()),
+            in_memory_torrent_repository: Arc::new(InMemoryTorrentRepository::default()),
             db_torrent_repository: Arc::new(DatabasePersistentTorrentRepository::new(database)),
         })
     }
@@ -658,7 +658,7 @@ impl Tracker {
 
     /// It returns the data for a `scrape` response.
     fn get_swarm_metadata(&self, info_hash: &InfoHash) -> SwarmMetadata {
-        self.torrents.get_swarm_metadata(info_hash)
+        self.in_memory_torrent_repository.get_swarm_metadata(info_hash)
     }
 
     /// It loads the torrents from database into memory. It only loads the torrent entry list with the number of seeders for each torrent.
@@ -672,7 +672,7 @@ impl Tracker {
     pub fn load_torrents_from_database(&self) -> Result<(), databases::error::Error> {
         let persistent_torrents = self.db_torrent_repository.load_all()?;
 
-        self.torrents.import_persistent(&persistent_torrents);
+        self.in_memory_torrent_repository.import_persistent(&persistent_torrents);
 
         Ok(())
     }
@@ -683,7 +683,7 @@ impl Tracker {
     ///
     /// It filters out the client making the request.
     fn get_peers_for(&self, info_hash: &InfoHash, peer: &peer::Peer, limit: usize) -> Vec<Arc<peer::Peer>> {
-        self.torrents.get_peers_for(info_hash, peer, limit)
+        self.in_memory_torrent_repository.get_peers_for(info_hash, peer, limit)
     }
 
     /// # Context: Tracker
@@ -691,7 +691,7 @@ impl Tracker {
     /// Get torrent peers for a given torrent.
     #[must_use]
     pub fn get_torrent_peers(&self, info_hash: &InfoHash) -> Vec<Arc<peer::Peer>> {
-        self.torrents.get_torrent_peers(info_hash)
+        self.in_memory_torrent_repository.get_torrent_peers(info_hash)
     }
 
     /// It updates the torrent entry in memory, it also stores in the database
@@ -701,14 +701,14 @@ impl Tracker {
     /// # Context: Tracker
     #[must_use]
     pub fn upsert_peer_and_get_stats(&self, info_hash: &InfoHash, peer: &peer::Peer) -> SwarmMetadata {
-        let swarm_metadata_before = match self.torrents.get_opt_swarm_metadata(info_hash) {
+        let swarm_metadata_before = match self.in_memory_torrent_repository.get_opt_swarm_metadata(info_hash) {
             Some(swarm_metadata) => swarm_metadata,
             None => SwarmMetadata::zeroed(),
         };
 
-        self.torrents.upsert_peer(info_hash, peer);
+        self.in_memory_torrent_repository.upsert_peer(info_hash, peer);
 
-        let swarm_metadata_after = match self.torrents.get_opt_swarm_metadata(info_hash) {
+        let swarm_metadata_after = match self.in_memory_torrent_repository.get_opt_swarm_metadata(info_hash) {
             Some(swarm_metadata) => swarm_metadata,
             None => SwarmMetadata::zeroed(),
         };
@@ -741,7 +741,7 @@ impl Tracker {
     /// Panics if unable to get the torrent metrics.
     #[must_use]
     pub fn get_torrents_metrics(&self) -> TorrentsMetrics {
-        self.torrents.get_torrents_metrics()
+        self.in_memory_torrent_repository.get_torrents_metrics()
     }
 
     /// Remove inactive peers and (optionally) peerless torrents.
@@ -751,10 +751,11 @@ impl Tracker {
         let current_cutoff = CurrentClock::now_sub(&Duration::from_secs(u64::from(self.config.tracker_policy.max_peer_timeout)))
             .unwrap_or_default();
 
-        self.torrents.remove_inactive_peers(current_cutoff);
+        self.in_memory_torrent_repository.remove_inactive_peers(current_cutoff);
 
         if self.config.tracker_policy.remove_peerless_torrents {
-            self.torrents.remove_peerless_torrents(&self.config.tracker_policy);
+            self.in_memory_torrent_repository
+                .remove_peerless_torrents(&self.config.tracker_policy);
         }
     }
 
@@ -1505,11 +1506,14 @@ mod tests {
                 assert_eq!(swarm_stats.downloaded, 1);
 
                 // Remove the newly updated torrent from memory
-                let _unused = tracker.torrents.remove(&info_hash);
+                let _unused = tracker.in_memory_torrent_repository.remove(&info_hash);
 
                 tracker.load_torrents_from_database().unwrap();
 
-                let torrent_entry = tracker.torrents.get(&info_hash).expect("it should be able to get entry");
+                let torrent_entry = tracker
+                    .in_memory_torrent_repository
+                    .get(&info_hash)
+                    .expect("it should be able to get entry");
 
                 // It persists the number of completed peers.
                 assert_eq!(torrent_entry.get_swarm_metadata().downloaded, 1);
diff --git a/src/core/services/torrent.rs b/src/core/services/torrent.rs
index 7f99451eb..032b526dd 100644
--- a/src/core/services/torrent.rs
+++ b/src/core/services/torrent.rs
@@ -45,7 +45,7 @@ pub struct BasicInfo {
 
 /// It returns all the information the tracker has about one torrent in a [Info] struct.
 pub async fn get_torrent_info(tracker: Arc<Tracker>, info_hash: &InfoHash) -> Option<Info> {
-    let torrent_entry_option = tracker.torrents.get(info_hash);
+    let torrent_entry_option = tracker.in_memory_torrent_repository.get(info_hash);
 
     let torrent_entry = torrent_entry_option?;
 
@@ -68,7 +68,7 @@ pub async fn get_torrent_info(tracker: Arc<Tracker>, info_hash: &InfoHash) -> Op
 pub async fn get_torrents_page(tracker: Arc<Tracker>, pagination: Option<&Pagination>) -> Vec<BasicInfo> {
     let mut basic_infos: Vec<BasicInfo> = vec![];
 
-    for (info_hash, torrent_entry) in tracker.torrents.get_paginated(pagination) {
+    for (info_hash, torrent_entry) in tracker.in_memory_torrent_repository.get_paginated(pagination) {
         let stats = torrent_entry.get_swarm_metadata();
 
         basic_infos.push(BasicInfo {
@@ -87,7 +87,11 @@ pub async fn get_torrents(tracker: Arc<Tracker>, info_hashes: &[InfoHash]) -> Ve
     let mut basic_infos: Vec<BasicInfo> = vec![];
 
     for info_hash in info_hashes {
-        if let Some(stats) = tracker.torrents.get(info_hash).map(|t| t.get_swarm_metadata()) {
+        if let Some(stats) = tracker
+            .in_memory_torrent_repository
+            .get(info_hash)
+            .map(|t| t.get_swarm_metadata())
+        {
             basic_infos.push(BasicInfo {
                 info_hash: *info_hash,
                 seeders: u64::from(stats.complete),

From 6332261af8a6a5e5d6de235283187d3440325133 Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 17:12:26 +0000
Subject: [PATCH 04/11] refactor: [#1201] extract TorrentsManager

---
 src/core/mod.rs             | 35 ++++++++++----------
 src/core/torrent/manager.rs | 64 +++++++++++++++++++++++++++++++++++++
 src/core/torrent/mod.rs     |  1 +
 3 files changed, 81 insertions(+), 19 deletions(-)
 create mode 100644 src/core/torrent/manager.rs

diff --git a/src/core/mod.rs b/src/core/mod.rs
index c9a7e9dc3..61f194f3d 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -451,12 +451,11 @@ pub mod peer_tests;
 
 use std::net::IpAddr;
 use std::sync::Arc;
-use std::time::Duration;
 
 use bittorrent_primitives::info_hash::InfoHash;
+use torrent::manager::TorrentsManager;
 use torrent::repository::in_memory::InMemoryTorrentRepository;
 use torrent::repository::persisted::DatabasePersistentTorrentRepository;
-use torrust_tracker_clock::clock::Time;
 use torrust_tracker_configuration::{AnnouncePolicy, Core, TORRENT_PEERS_LIMIT};
 use torrust_tracker_primitives::core::{AnnounceData, ScrapeData};
 use torrust_tracker_primitives::peer;
@@ -464,7 +463,6 @@ use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
 use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
 
 use crate::core::databases::Database;
-use crate::CurrentClock;
 
 /// The domain layer tracker service.
 ///
@@ -491,6 +489,9 @@ pub struct Tracker {
 
     /// The persistent torrents repository.
     db_torrent_repository: Arc<DatabasePersistentTorrentRepository>,
+
+    /// The service to run torrents tasks.
+    torrents_manager: Arc<TorrentsManager>,
 }
 
 /// How many peers the peer announcing wants in the announce response.
@@ -546,12 +547,20 @@ impl Tracker {
         database: &Arc<Box<dyn Database>>,
         whitelist_authorization: &Arc<whitelist::authorization::Authorization>,
     ) -> Result<Tracker, databases::error::Error> {
+        let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
+        let db_torrent_repository = Arc::new(DatabasePersistentTorrentRepository::new(database));
+
         Ok(Tracker {
             config: config.clone(),
             database: database.clone(),
             whitelist_authorization: whitelist_authorization.clone(),
-            in_memory_torrent_repository: Arc::new(InMemoryTorrentRepository::default()),
-            db_torrent_repository: Arc::new(DatabasePersistentTorrentRepository::new(database)),
+            in_memory_torrent_repository: in_memory_torrent_repository.clone(),
+            db_torrent_repository: db_torrent_repository.clone(),
+            torrents_manager: Arc::new(TorrentsManager::new(
+                config,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+            )),
         })
     }
 
@@ -670,11 +679,7 @@ impl Tracker {
     ///
     /// Will return a `database::Error` if unable to load the list of `persistent_torrents` from the database.
     pub fn load_torrents_from_database(&self) -> Result<(), databases::error::Error> {
-        let persistent_torrents = self.db_torrent_repository.load_all()?;
-
-        self.in_memory_torrent_repository.import_persistent(&persistent_torrents);
-
-        Ok(())
+        self.torrents_manager.load_torrents_from_database()
     }
 
     /// # Context: Tracker
@@ -748,15 +753,7 @@ impl Tracker {
     ///
     /// # Context: Tracker
     pub fn cleanup_torrents(&self) {
-        let current_cutoff = CurrentClock::now_sub(&Duration::from_secs(u64::from(self.config.tracker_policy.max_peer_timeout)))
-            .unwrap_or_default();
-
-        self.in_memory_torrent_repository.remove_inactive_peers(current_cutoff);
-
-        if self.config.tracker_policy.remove_peerless_torrents {
-            self.in_memory_torrent_repository
-                .remove_peerless_torrents(&self.config.tracker_policy);
-        }
+        self.torrents_manager.cleanup_torrents();
     }
 
     /// It drops the database tables.
diff --git a/src/core/torrent/manager.rs b/src/core/torrent/manager.rs
new file mode 100644
index 000000000..261376755
--- /dev/null
+++ b/src/core/torrent/manager.rs
@@ -0,0 +1,64 @@
+use std::sync::Arc;
+use std::time::Duration;
+
+use torrust_tracker_clock::clock::Time;
+use torrust_tracker_configuration::Core;
+
+use super::repository::in_memory::InMemoryTorrentRepository;
+use super::repository::persisted::DatabasePersistentTorrentRepository;
+use crate::core::databases;
+use crate::CurrentClock;
+
+pub struct TorrentsManager {
+    /// The tracker configuration.
+    config: Core,
+
+    /// The in-memory torrents repository.
+    in_memory_torrent_repository: Arc<InMemoryTorrentRepository>,
+
+    /// The persistent torrents repository.
+    db_torrent_repository: Arc<DatabasePersistentTorrentRepository>,
+}
+
+impl TorrentsManager {
+    #[must_use]
+    pub fn new(
+        config: &Core,
+        in_memory_torrent_repository: &Arc<InMemoryTorrentRepository>,
+        db_torrent_repository: &Arc<DatabasePersistentTorrentRepository>,
+    ) -> Self {
+        Self {
+            config: config.clone(),
+            in_memory_torrent_repository: in_memory_torrent_repository.clone(),
+            db_torrent_repository: db_torrent_repository.clone(),
+        }
+    }
+
+    /// It loads the torrents from database into memory. It only loads the
+    /// torrent entry list with the number of seeders for each torrent. Peers
+    /// data is not persisted.
+    ///
+    /// # Errors
+    ///
+    /// Will return a `database::Error` if unable to load the list of `persistent_torrents` from the database.
+    pub fn load_torrents_from_database(&self) -> Result<(), databases::error::Error> {
+        let persistent_torrents = self.db_torrent_repository.load_all()?;
+
+        self.in_memory_torrent_repository.import_persistent(&persistent_torrents);
+
+        Ok(())
+    }
+
+    /// Remove inactive peers and (optionally) peerless torrents.
+    pub fn cleanup_torrents(&self) {
+        let current_cutoff = CurrentClock::now_sub(&Duration::from_secs(u64::from(self.config.tracker_policy.max_peer_timeout)))
+            .unwrap_or_default();
+
+        self.in_memory_torrent_repository.remove_inactive_peers(current_cutoff);
+
+        if self.config.tracker_policy.remove_peerless_torrents {
+            self.in_memory_torrent_repository
+                .remove_peerless_torrents(&self.config.tracker_policy);
+        }
+    }
+}
diff --git a/src/core/torrent/mod.rs b/src/core/torrent/mod.rs
index 3e3e065f2..95a5ff1eb 100644
--- a/src/core/torrent/mod.rs
+++ b/src/core/torrent/mod.rs
@@ -25,6 +25,7 @@
 //! - The number of peers that have NOT completed downloading the torrent and are still active, that means they are actively participating in the network.
 //!   Peer that don not have a full copy of the torrent data are called "leechers".
 //!
+pub mod manager;
 pub mod repository;
 
 use torrust_tracker_torrent_repository::TorrentsSkipMapMutexStd;

From 4e3dbae05b8e7999f08bf8035575499c300bd496 Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 17:34:13 +0000
Subject: [PATCH 05/11] refactor: [#1201] inject new extracted sercvies in core
 tracker

---
 src/app_test.rs                          |  23 +++-
 src/bootstrap/app.rs                     |  19 ++-
 src/core/mod.rs                          |  76 ++++++++---
 src/core/services/mod.rs                 |  15 ++-
 src/core/services/statistics/mod.rs      |  21 +++-
 src/core/services/torrent.rs             | 154 ++++++++++++++++++-----
 src/servers/http/v1/handlers/announce.rs |  20 ++-
 src/servers/http/v1/handlers/scrape.rs   |  80 ++++++++++--
 src/servers/http/v1/services/announce.rs |  43 +++++--
 src/servers/http/v1/services/scrape.rs   |  45 +++++--
 src/servers/udp/handlers.rs              |  68 ++++++++--
 11 files changed, 471 insertions(+), 93 deletions(-)

diff --git a/src/app_test.rs b/src/app_test.rs
index 929a23418..5f189f391 100644
--- a/src/app_test.rs
+++ b/src/app_test.rs
@@ -9,6 +9,9 @@ use crate::core::authentication::key::repository::persisted::DatabaseKeyReposito
 use crate::core::authentication::service::{self, AuthenticationService};
 use crate::core::databases::Database;
 use crate::core::services::initialize_database;
+use crate::core::torrent::manager::TorrentsManager;
+use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository;
+use crate::core::torrent::repository::persisted::DatabasePersistentTorrentRepository;
 use crate::core::whitelist;
 use crate::core::whitelist::repository::in_memory::InMemoryWhitelist;
 
@@ -22,6 +25,9 @@ pub fn initialize_tracker_dependencies(
     Arc<InMemoryWhitelist>,
     Arc<whitelist::authorization::Authorization>,
     Arc<AuthenticationService>,
+    Arc<InMemoryTorrentRepository>,
+    Arc<DatabasePersistentTorrentRepository>,
+    Arc<TorrentsManager>,
 ) {
     let database = initialize_database(config);
     let in_memory_whitelist = Arc::new(InMemoryWhitelist::default());
@@ -36,6 +42,21 @@ pub fn initialize_tracker_dependencies(
         &db_key_repository.clone(),
         &in_memory_key_repository.clone(),
     ));
+    let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
+    let db_torrent_repository = Arc::new(DatabasePersistentTorrentRepository::new(&database));
+    let torrents_manager = Arc::new(TorrentsManager::new(
+        &config.core,
+        &in_memory_torrent_repository,
+        &db_torrent_repository,
+    ));
 
-    (database, in_memory_whitelist, whitelist_authorization, authentication_service)
+    (
+        database,
+        in_memory_whitelist,
+        whitelist_authorization,
+        authentication_service,
+        in_memory_torrent_repository,
+        db_torrent_repository,
+        torrents_manager,
+    )
 }
diff --git a/src/bootstrap/app.rs b/src/bootstrap/app.rs
index a0c7887cf..ea7d7f030 100644
--- a/src/bootstrap/app.rs
+++ b/src/bootstrap/app.rs
@@ -27,6 +27,9 @@ use crate::core::authentication::key::repository::in_memory::InMemoryKeyReposito
 use crate::core::authentication::key::repository::persisted::DatabaseKeyRepository;
 use crate::core::authentication::service;
 use crate::core::services::{initialize_database, initialize_tracker, initialize_whitelist_manager, statistics};
+use crate::core::torrent::manager::TorrentsManager;
+use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository;
+use crate::core::torrent::repository::persisted::DatabasePersistentTorrentRepository;
 use crate::core::whitelist;
 use crate::core::whitelist::repository::in_memory::InMemoryWhitelist;
 use crate::servers::udp::server::banning::BanService;
@@ -103,8 +106,22 @@ pub fn initialize_app_container(configuration: &Configuration) -> AppContainer {
         &db_key_repository.clone(),
         &in_memory_key_repository.clone(),
     ));
+    let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
+    let db_torrent_repository = Arc::new(DatabasePersistentTorrentRepository::new(&database));
+    let torrents_manager = Arc::new(TorrentsManager::new(
+        &configuration.core,
+        &in_memory_torrent_repository,
+        &db_torrent_repository,
+    ));
 
-    let tracker = Arc::new(initialize_tracker(configuration, &database, &whitelist_authorization));
+    let tracker = Arc::new(initialize_tracker(
+        configuration,
+        &database,
+        &whitelist_authorization,
+        &in_memory_torrent_repository,
+        &db_torrent_repository,
+        &torrents_manager,
+    ));
 
     AppContainer {
         tracker,
diff --git a/src/core/mod.rs b/src/core/mod.rs
index 61f194f3d..161607857 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -546,21 +546,17 @@ impl Tracker {
         config: &Core,
         database: &Arc<Box<dyn Database>>,
         whitelist_authorization: &Arc<whitelist::authorization::Authorization>,
+        in_memory_torrent_repository: &Arc<InMemoryTorrentRepository>,
+        db_torrent_repository: &Arc<DatabasePersistentTorrentRepository>,
+        torrents_manager: &Arc<TorrentsManager>,
     ) -> Result<Tracker, databases::error::Error> {
-        let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
-        let db_torrent_repository = Arc::new(DatabasePersistentTorrentRepository::new(database));
-
         Ok(Tracker {
             config: config.clone(),
             database: database.clone(),
             whitelist_authorization: whitelist_authorization.clone(),
             in_memory_torrent_repository: in_memory_torrent_repository.clone(),
             db_torrent_repository: db_torrent_repository.clone(),
-            torrents_manager: Arc::new(TorrentsManager::new(
-                config,
-                &in_memory_torrent_repository,
-                &db_torrent_repository,
-            )),
+            torrents_manager: torrents_manager.clone(),
         })
     }
 
@@ -802,21 +798,49 @@ mod tests {
         fn public_tracker() -> Tracker {
             let config = configuration::ephemeral_public();
 
-            let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
-
-            initialize_tracker(&config, &database, &whitelist_authorization)
+            let (
+                database,
+                _in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
+
+            initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            )
         }
 
         fn whitelisted_tracker() -> (Tracker, Arc<whitelist::authorization::Authorization>, Arc<WhiteListManager>) {
             let config = configuration::ephemeral_listed();
 
-            let (database, in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
+            let (
+                database,
+                in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
 
             let whitelist_manager = initialize_whitelist_manager(database.clone(), in_memory_whitelist.clone());
 
-            let tracker = initialize_tracker(&config, &database, &whitelist_authorization);
+            let tracker = initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            );
 
             (tracker, whitelist_authorization, whitelist_manager)
         }
@@ -825,10 +849,24 @@ mod tests {
             let mut config = configuration::ephemeral_listed();
             config.core.tracker_policy.persistent_torrent_completed_stat = true;
 
-            let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
-
-            initialize_tracker(&config, &database, &whitelist_authorization)
+            let (
+                database,
+                _in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
+
+            initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            )
         }
 
         fn sample_info_hash() -> InfoHash {
diff --git a/src/core/services/mod.rs b/src/core/services/mod.rs
index 611ea24d2..f5d9bd375 100644
--- a/src/core/services/mod.rs
+++ b/src/core/services/mod.rs
@@ -14,6 +14,9 @@ use torrust_tracker_configuration::v2_0_0::database;
 use torrust_tracker_configuration::Configuration;
 
 use super::databases::{self, Database};
+use super::torrent::manager::TorrentsManager;
+use super::torrent::repository::in_memory::InMemoryTorrentRepository;
+use super::torrent::repository::persisted::DatabasePersistentTorrentRepository;
 use super::whitelist;
 use super::whitelist::manager::WhiteListManager;
 use super::whitelist::repository::in_memory::InMemoryWhitelist;
@@ -30,8 +33,18 @@ pub fn initialize_tracker(
     config: &Configuration,
     database: &Arc<Box<dyn Database>>,
     whitelist_authorization: &Arc<whitelist::authorization::Authorization>,
+    in_memory_torrent_repository: &Arc<InMemoryTorrentRepository>,
+    db_torrent_repository: &Arc<DatabasePersistentTorrentRepository>,
+    torrents_manager: &Arc<TorrentsManager>,
 ) -> Tracker {
-    match Tracker::new(&Arc::new(config).core, database, whitelist_authorization) {
+    match Tracker::new(
+        &Arc::new(config).core,
+        database,
+        whitelist_authorization,
+        in_memory_torrent_repository,
+        db_torrent_repository,
+        torrents_manager,
+    ) {
         Ok(tracker) => tracker,
         Err(error) => {
             panic!("{}", error)
diff --git a/src/core/services/statistics/mod.rs b/src/core/services/statistics/mod.rs
index cc59bcf12..9e4696f48 100644
--- a/src/core/services/statistics/mod.rs
+++ b/src/core/services/statistics/mod.rs
@@ -132,12 +132,27 @@ mod tests {
     async fn the_statistics_service_should_return_the_tracker_metrics() {
         let config = tracker_configuration();
 
-        let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-            initialize_tracker_dependencies(&config);
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            _authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(&config);
+
         let (_stats_event_sender, stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
         let stats_repository = Arc::new(stats_repository);
 
-        let tracker = Arc::new(initialize_tracker(&config, &database, &whitelist_authorization));
+        let tracker = Arc::new(initialize_tracker(
+            &config,
+            &database,
+            &whitelist_authorization,
+            &in_memory_torrent_repository,
+            &db_torrent_repository,
+            &torrents_manager,
+        ));
 
         let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP)));
 
diff --git a/src/core/services/torrent.rs b/src/core/services/torrent.rs
index 032b526dd..1e3f67eba 100644
--- a/src/core/services/torrent.rs
+++ b/src/core/services/torrent.rs
@@ -145,10 +145,24 @@ mod tests {
         async fn should_return_none_if_the_tracker_does_not_have_the_torrent() {
             let config = tracker_configuration();
 
-            let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
-
-            let tracker = initialize_tracker(&config, &database, &whitelist_authorization);
+            let (
+                database,
+                _in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
+
+            let tracker = initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            );
 
             let tracker = Arc::new(tracker);
 
@@ -165,10 +179,24 @@ mod tests {
         async fn should_return_the_torrent_info_if_the_tracker_has_the_torrent() {
             let config = tracker_configuration();
 
-            let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(&config, &database, &whitelist_authorization));
+            let (
+                database,
+                _in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
+
+            let tracker = Arc::new(initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            ));
 
             let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
             let info_hash = InfoHash::from_str(&hash).unwrap();
@@ -211,10 +239,24 @@ mod tests {
         async fn should_return_an_empty_result_if_the_tracker_does_not_have_any_torrent() {
             let config = tracker_configuration();
 
-            let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(&config, &database, &whitelist_authorization));
+            let (
+                database,
+                _in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
+
+            let tracker = Arc::new(initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            ));
 
             let torrents = get_torrents_page(tracker.clone(), Some(&Pagination::default())).await;
 
@@ -225,10 +267,24 @@ mod tests {
         async fn should_return_a_summarized_info_for_all_torrents() {
             let config = tracker_configuration();
 
-            let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(&config, &database, &whitelist_authorization));
+            let (
+                database,
+                _in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
+
+            let tracker = Arc::new(initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            ));
 
             let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
             let info_hash = InfoHash::from_str(&hash).unwrap();
@@ -252,10 +308,24 @@ mod tests {
         async fn should_allow_limiting_the_number_of_torrents_in_the_result() {
             let config = tracker_configuration();
 
-            let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(&config, &database, &whitelist_authorization));
+            let (
+                database,
+                _in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
+
+            let tracker = Arc::new(initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            ));
 
             let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
             let info_hash1 = InfoHash::from_str(&hash1).unwrap();
@@ -277,10 +347,24 @@ mod tests {
         async fn should_allow_using_pagination_in_the_result() {
             let config = tracker_configuration();
 
-            let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(&config, &database, &whitelist_authorization));
+            let (
+                database,
+                _in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
+
+            let tracker = Arc::new(initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            ));
 
             let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
             let info_hash1 = InfoHash::from_str(&hash1).unwrap();
@@ -311,10 +395,24 @@ mod tests {
         async fn should_return_torrents_ordered_by_info_hash() {
             let config = tracker_configuration();
 
-            let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(&config, &database, &whitelist_authorization));
+            let (
+                database,
+                _in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
+
+            let tracker = Arc::new(initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            ));
 
             let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
             let info_hash1 = InfoHash::from_str(&hash1).unwrap();
diff --git a/src/servers/http/v1/handlers/announce.rs b/src/servers/http/v1/handlers/announce.rs
index c42981d4c..b18671422 100644
--- a/src/servers/http/v1/handlers/announce.rs
+++ b/src/servers/http/v1/handlers/announce.rs
@@ -274,12 +274,26 @@ mod tests {
 
     /// Initialize tracker's dependencies and tracker.
     fn initialize_tracker_and_deps(config: &Configuration) -> TrackerAndDeps {
-        let (database, _in_memory_whitelist, whitelist_authorization, authentication_service) =
-            initialize_tracker_dependencies(config);
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(config);
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
         let stats_event_sender = Arc::new(stats_event_sender);
 
-        let tracker = Arc::new(initialize_tracker(config, &database, &whitelist_authorization));
+        let tracker = Arc::new(initialize_tracker(
+            config,
+            &database,
+            &whitelist_authorization,
+            &in_memory_torrent_repository,
+            &db_torrent_repository,
+            &torrents_manager,
+        ));
 
         (tracker, stats_event_sender, whitelist_authorization, authentication_service)
     }
diff --git a/src/servers/http/v1/handlers/scrape.rs b/src/servers/http/v1/handlers/scrape.rs
index de4610a61..e619ba120 100644
--- a/src/servers/http/v1/handlers/scrape.rs
+++ b/src/servers/http/v1/handlers/scrape.rs
@@ -151,13 +151,27 @@ mod tests {
     ) {
         let config = configuration::ephemeral_private();
 
-        let (database, _in_memory_whitelist, whitelist_authorization, authentication_service) =
-            initialize_tracker_dependencies(&config);
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(&config);
 
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
 
         (
-            initialize_tracker(&config, &database, &whitelist_authorization),
+            initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            ),
             stats_event_sender,
             authentication_service,
         )
@@ -170,13 +184,27 @@ mod tests {
     ) {
         let config = configuration::ephemeral_listed();
 
-        let (database, _in_memory_whitelist, whitelist_authorization, authentication_service) =
-            initialize_tracker_dependencies(&config);
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(&config);
 
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
 
         (
-            initialize_tracker(&config, &database, &whitelist_authorization),
+            initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            ),
             stats_event_sender,
             authentication_service,
         )
@@ -189,13 +217,27 @@ mod tests {
     ) {
         let config = configuration::ephemeral_with_reverse_proxy();
 
-        let (database, _in_memory_whitelist, whitelist_authorization, authentication_service) =
-            initialize_tracker_dependencies(&config);
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(&config);
 
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
 
         (
-            initialize_tracker(&config, &database, &whitelist_authorization),
+            initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            ),
             stats_event_sender,
             authentication_service,
         )
@@ -208,13 +250,27 @@ mod tests {
     ) {
         let config = configuration::ephemeral_without_reverse_proxy();
 
-        let (database, _in_memory_whitelist, whitelist_authorization, authentication_service) =
-            initialize_tracker_dependencies(&config);
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(&config);
 
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
 
         (
-            initialize_tracker(&config, &database, &whitelist_authorization),
+            initialize_tracker(
+                &config,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            ),
             stats_event_sender,
             authentication_service,
         )
diff --git a/src/servers/http/v1/services/announce.rs b/src/servers/http/v1/services/announce.rs
index 018348d7e..99724f728 100644
--- a/src/servers/http/v1/services/announce.rs
+++ b/src/servers/http/v1/services/announce.rs
@@ -73,12 +73,26 @@ mod tests {
     fn public_tracker() -> (Tracker, Arc<Option<Box<dyn Sender>>>) {
         let config = configuration::ephemeral_public();
 
-        let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-            initialize_tracker_dependencies(&config);
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            _authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(&config);
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
         let stats_event_sender = Arc::new(stats_event_sender);
 
-        let tracker = initialize_tracker(&config, &database, &whitelist_authorization);
+        let tracker = initialize_tracker(
+            &config,
+            &database,
+            &whitelist_authorization,
+            &in_memory_torrent_repository,
+            &db_torrent_repository,
+            &torrents_manager,
+        );
 
         (tracker, stats_event_sender)
     }
@@ -132,10 +146,25 @@ mod tests {
         fn test_tracker_factory() -> Tracker {
             let config = configuration::ephemeral();
 
-            let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                initialize_tracker_dependencies(&config);
-
-            Tracker::new(&config.core, &database, &whitelist_authorization).unwrap()
+            let (
+                database,
+                _in_memory_whitelist,
+                whitelist_authorization,
+                _authentication_service,
+                in_memory_torrent_repository,
+                db_torrent_repository,
+                torrents_manager,
+            ) = initialize_tracker_dependencies(&config);
+
+            Tracker::new(
+                &config.core,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            )
+            .unwrap()
         }
 
         #[tokio::test]
diff --git a/src/servers/http/v1/services/scrape.rs b/src/servers/http/v1/services/scrape.rs
index 9ad741234..c9e657d11 100644
--- a/src/servers/http/v1/services/scrape.rs
+++ b/src/servers/http/v1/services/scrape.rs
@@ -87,10 +87,24 @@ mod tests {
     fn public_tracker() -> Tracker {
         let config = configuration::ephemeral_public();
 
-        let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-            initialize_tracker_dependencies(&config);
-
-        initialize_tracker(&config, &database, &whitelist_authorization)
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            _authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(&config);
+
+        initialize_tracker(
+            &config,
+            &database,
+            &whitelist_authorization,
+            &in_memory_torrent_repository,
+            &db_torrent_repository,
+            &torrents_manager,
+        )
     }
 
     fn sample_info_hashes() -> Vec<InfoHash> {
@@ -116,10 +130,25 @@ mod tests {
     fn test_tracker_factory() -> Tracker {
         let config = configuration::ephemeral();
 
-        let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-            initialize_tracker_dependencies(&config);
-
-        Tracker::new(&config.core, &database, &whitelist_authorization).unwrap()
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            _authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(&config);
+
+        Tracker::new(
+            &config.core,
+            &database,
+            &whitelist_authorization,
+            &in_memory_torrent_repository,
+            &db_torrent_repository,
+            &torrents_manager,
+        )
+        .unwrap()
     }
 
     mod with_real_data {
diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs
index feeca4e40..840b789a1 100644
--- a/src/servers/udp/handlers.rs
+++ b/src/servers/udp/handlers.rs
@@ -516,13 +516,27 @@ mod tests {
     }
 
     fn initialize_tracker_and_deps(config: &Configuration) -> TrackerAndDeps {
-        let (database, in_memory_whitelist, whitelist_authorization, _authentication_service) =
-            initialize_tracker_dependencies(config);
+        let (
+            database,
+            in_memory_whitelist,
+            whitelist_authorization,
+            _authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(config);
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
         let stats_event_sender = Arc::new(stats_event_sender);
         let whitelist_manager = initialize_whitelist_manager(database.clone(), in_memory_whitelist.clone());
 
-        let tracker = Arc::new(initialize_tracker(config, &database, &whitelist_authorization));
+        let tracker = Arc::new(initialize_tracker(
+            config,
+            &database,
+            &whitelist_authorization,
+            &in_memory_torrent_repository,
+            &db_torrent_repository,
+            &torrents_manager,
+        ));
 
         (
             tracker,
@@ -630,10 +644,27 @@ mod tests {
     fn test_tracker_factory() -> (Arc<Tracker>, Arc<whitelist::authorization::Authorization>) {
         let config = tracker_configuration();
 
-        let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-            initialize_tracker_dependencies(&config);
-
-        let tracker = Arc::new(Tracker::new(&config.core, &database, &whitelist_authorization).unwrap());
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            _authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(&config);
+
+        let tracker = Arc::new(
+            Tracker::new(
+                &config.core,
+                &database,
+                &whitelist_authorization,
+                &in_memory_torrent_repository,
+                &db_torrent_repository,
+                &torrents_manager,
+            )
+            .unwrap(),
+        );
 
         (tracker, whitelist_authorization)
     }
@@ -1378,8 +1409,15 @@ mod tests {
                 async fn the_peer_ip_should_be_changed_to_the_external_ip_in_the_tracker_configuration() {
                     let config = Arc::new(TrackerConfigurationBuilder::default().with_external_ip("::126.0.0.1").into());
 
-                    let (database, _in_memory_whitelist, whitelist_authorization, _authentication_service) =
-                        initialize_tracker_dependencies(&config);
+                    let (
+                        database,
+                        _in_memory_whitelist,
+                        whitelist_authorization,
+                        _authentication_service,
+                        in_memory_torrent_repository,
+                        db_torrent_repository,
+                        torrents_manager,
+                    ) = initialize_tracker_dependencies(&config);
 
                     let mut stats_event_sender_mock = statistics::event::sender::MockSender::new();
                     stats_event_sender_mock
@@ -1390,7 +1428,17 @@ mod tests {
                     let stats_event_sender: Arc<Option<Box<dyn statistics::event::sender::Sender>>> =
                         Arc::new(Some(Box::new(stats_event_sender_mock)));
 
-                    let tracker = Arc::new(core::Tracker::new(&config.core, &database, &whitelist_authorization).unwrap());
+                    let tracker = Arc::new(
+                        core::Tracker::new(
+                            &config.core,
+                            &database,
+                            &whitelist_authorization,
+                            &in_memory_torrent_repository,
+                            &db_torrent_repository,
+                            &torrents_manager,
+                        )
+                        .unwrap(),
+                    );
 
                     let loopback_ipv4 = Ipv4Addr::new(127, 0, 0, 1);
                     let loopback_ipv6 = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);

From 6fb632ee841dc2a10421a20ba935585c17099d85 Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 17:48:17 +0000
Subject: [PATCH 06/11] refactor: [#1201] remove duplicate code

---
 src/core/services/torrent.rs             | 148 ++++++-----------------
 src/servers/http/v1/handlers/announce.rs |   1 +
 src/servers/udp/handlers.rs              |   1 +
 3 files changed, 37 insertions(+), 113 deletions(-)

diff --git a/src/core/services/torrent.rs b/src/core/services/torrent.rs
index 1e3f67eba..f8da88d6f 100644
--- a/src/core/services/torrent.rs
+++ b/src/core/services/torrent.rs
@@ -107,10 +107,37 @@ pub async fn get_torrents(tracker: Arc<Tracker>, info_hashes: &[InfoHash]) -> Ve
 #[cfg(test)]
 mod tests {
     use std::net::{IpAddr, Ipv4Addr, SocketAddr};
+    use std::sync::Arc;
 
     use aquatic_udp_protocol::{AnnounceEvent, NumberOfBytes, PeerId};
+    use torrust_tracker_configuration::Configuration;
     use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch};
 
+    use crate::app_test::initialize_tracker_dependencies;
+    use crate::core::services::initialize_tracker;
+    use crate::core::Tracker;
+
+    fn initialize_tracker_and_deps(config: &Configuration) -> Arc<Tracker> {
+        let (
+            database,
+            _in_memory_whitelist,
+            whitelist_authorization,
+            _authentication_service,
+            in_memory_torrent_repository,
+            db_torrent_repository,
+            torrents_manager,
+        ) = initialize_tracker_dependencies(config);
+
+        Arc::new(initialize_tracker(
+            config,
+            &database,
+            &whitelist_authorization,
+            &in_memory_torrent_repository,
+            &db_torrent_repository,
+            &torrents_manager,
+        ))
+    }
+
     fn sample_peer() -> peer::Peer {
         peer::Peer {
             peer_id: PeerId(*b"-qB00000000000000000"),
@@ -134,7 +161,7 @@ mod tests {
 
         use crate::app_test::initialize_tracker_dependencies;
         use crate::core::services::initialize_tracker;
-        use crate::core::services::torrent::tests::sample_peer;
+        use crate::core::services::torrent::tests::{initialize_tracker_and_deps, sample_peer};
         use crate::core::services::torrent::{get_torrent_info, Info};
 
         pub fn tracker_configuration() -> Configuration {
@@ -179,24 +206,7 @@ mod tests {
         async fn should_return_the_torrent_info_if_the_tracker_has_the_torrent() {
             let config = tracker_configuration();
 
-            let (
-                database,
-                _in_memory_whitelist,
-                whitelist_authorization,
-                _authentication_service,
-                in_memory_torrent_repository,
-                db_torrent_repository,
-                torrents_manager,
-            ) = initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(
-                &config,
-                &database,
-                &whitelist_authorization,
-                &in_memory_torrent_repository,
-                &db_torrent_repository,
-                &torrents_manager,
-            ));
+            let tracker = initialize_tracker_and_deps(&config);
 
             let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
             let info_hash = InfoHash::from_str(&hash).unwrap();
@@ -220,15 +230,12 @@ mod tests {
     mod searching_for_torrents {
 
         use std::str::FromStr;
-        use std::sync::Arc;
 
         use bittorrent_primitives::info_hash::InfoHash;
         use torrust_tracker_configuration::Configuration;
         use torrust_tracker_test_helpers::configuration;
 
-        use crate::app_test::initialize_tracker_dependencies;
-        use crate::core::services::initialize_tracker;
-        use crate::core::services::torrent::tests::sample_peer;
+        use crate::core::services::torrent::tests::{initialize_tracker_and_deps, sample_peer};
         use crate::core::services::torrent::{get_torrents_page, BasicInfo, Pagination};
 
         pub fn tracker_configuration() -> Configuration {
@@ -239,24 +246,7 @@ mod tests {
         async fn should_return_an_empty_result_if_the_tracker_does_not_have_any_torrent() {
             let config = tracker_configuration();
 
-            let (
-                database,
-                _in_memory_whitelist,
-                whitelist_authorization,
-                _authentication_service,
-                in_memory_torrent_repository,
-                db_torrent_repository,
-                torrents_manager,
-            ) = initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(
-                &config,
-                &database,
-                &whitelist_authorization,
-                &in_memory_torrent_repository,
-                &db_torrent_repository,
-                &torrents_manager,
-            ));
+            let tracker = initialize_tracker_and_deps(&config);
 
             let torrents = get_torrents_page(tracker.clone(), Some(&Pagination::default())).await;
 
@@ -267,24 +257,7 @@ mod tests {
         async fn should_return_a_summarized_info_for_all_torrents() {
             let config = tracker_configuration();
 
-            let (
-                database,
-                _in_memory_whitelist,
-                whitelist_authorization,
-                _authentication_service,
-                in_memory_torrent_repository,
-                db_torrent_repository,
-                torrents_manager,
-            ) = initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(
-                &config,
-                &database,
-                &whitelist_authorization,
-                &in_memory_torrent_repository,
-                &db_torrent_repository,
-                &torrents_manager,
-            ));
+            let tracker = initialize_tracker_and_deps(&config);
 
             let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
             let info_hash = InfoHash::from_str(&hash).unwrap();
@@ -308,24 +281,7 @@ mod tests {
         async fn should_allow_limiting_the_number_of_torrents_in_the_result() {
             let config = tracker_configuration();
 
-            let (
-                database,
-                _in_memory_whitelist,
-                whitelist_authorization,
-                _authentication_service,
-                in_memory_torrent_repository,
-                db_torrent_repository,
-                torrents_manager,
-            ) = initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(
-                &config,
-                &database,
-                &whitelist_authorization,
-                &in_memory_torrent_repository,
-                &db_torrent_repository,
-                &torrents_manager,
-            ));
+            let tracker = initialize_tracker_and_deps(&config);
 
             let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
             let info_hash1 = InfoHash::from_str(&hash1).unwrap();
@@ -347,24 +303,7 @@ mod tests {
         async fn should_allow_using_pagination_in_the_result() {
             let config = tracker_configuration();
 
-            let (
-                database,
-                _in_memory_whitelist,
-                whitelist_authorization,
-                _authentication_service,
-                in_memory_torrent_repository,
-                db_torrent_repository,
-                torrents_manager,
-            ) = initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(
-                &config,
-                &database,
-                &whitelist_authorization,
-                &in_memory_torrent_repository,
-                &db_torrent_repository,
-                &torrents_manager,
-            ));
+            let tracker = initialize_tracker_and_deps(&config);
 
             let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
             let info_hash1 = InfoHash::from_str(&hash1).unwrap();
@@ -395,24 +334,7 @@ mod tests {
         async fn should_return_torrents_ordered_by_info_hash() {
             let config = tracker_configuration();
 
-            let (
-                database,
-                _in_memory_whitelist,
-                whitelist_authorization,
-                _authentication_service,
-                in_memory_torrent_repository,
-                db_torrent_repository,
-                torrents_manager,
-            ) = initialize_tracker_dependencies(&config);
-
-            let tracker = Arc::new(initialize_tracker(
-                &config,
-                &database,
-                &whitelist_authorization,
-                &in_memory_torrent_repository,
-                &db_torrent_repository,
-                &torrents_manager,
-            ));
+            let tracker = initialize_tracker_and_deps(&config);
 
             let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
             let info_hash1 = InfoHash::from_str(&hash1).unwrap();
diff --git a/src/servers/http/v1/handlers/announce.rs b/src/servers/http/v1/handlers/announce.rs
index b18671422..b0b54fa0d 100644
--- a/src/servers/http/v1/handlers/announce.rs
+++ b/src/servers/http/v1/handlers/announce.rs
@@ -283,6 +283,7 @@ mod tests {
             db_torrent_repository,
             torrents_manager,
         ) = initialize_tracker_dependencies(config);
+        
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
         let stats_event_sender = Arc::new(stats_event_sender);
 
diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs
index 840b789a1..6abbd95c6 100644
--- a/src/servers/udp/handlers.rs
+++ b/src/servers/udp/handlers.rs
@@ -525,6 +525,7 @@ mod tests {
             db_torrent_repository,
             torrents_manager,
         ) = initialize_tracker_dependencies(config);
+        
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
         let stats_event_sender = Arc::new(stats_event_sender);
         let whitelist_manager = initialize_whitelist_manager(database.clone(), in_memory_whitelist.clone());

From a4a2d678bb5a2cd3dfa87f05cf9f748e9efbc1bc Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 17:54:18 +0000
Subject: [PATCH 07/11] refactor: [#1201] remove pub fn from tracker

---
 src/core/mod.rs | 14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/src/core/mod.rs b/src/core/mod.rs
index 161607857..a1b496c56 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -666,18 +666,6 @@ impl Tracker {
         self.in_memory_torrent_repository.get_swarm_metadata(info_hash)
     }
 
-    /// It loads the torrents from database into memory. It only loads the torrent entry list with the number of seeders for each torrent.
-    /// Peers data is not persisted.
-    ///
-    /// # Context: Tracker
-    ///
-    /// # Errors
-    ///
-    /// Will return a `database::Error` if unable to load the list of `persistent_torrents` from the database.
-    pub fn load_torrents_from_database(&self) -> Result<(), databases::error::Error> {
-        self.torrents_manager.load_torrents_from_database()
-    }
-
     /// # Context: Tracker
     ///
     /// Get torrent peers for a given torrent and client.
@@ -1543,7 +1531,7 @@ mod tests {
                 // Remove the newly updated torrent from memory
                 let _unused = tracker.in_memory_torrent_repository.remove(&info_hash);
 
-                tracker.load_torrents_from_database().unwrap();
+                tracker.torrents_manager.load_torrents_from_database().unwrap();
 
                 let torrent_entry = tracker
                     .in_memory_torrent_repository

From bdc3f22a8c5e67a7a67a2589ced713373d227697 Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 18:01:09 +0000
Subject: [PATCH 08/11] refactor: [#1201] add database to app container y
 environments

---
 src/bootstrap/app.rs              | 1 +
 src/container.rs                  | 2 ++
 tests/servers/api/environment.rs  | 5 +++++
 tests/servers/http/environment.rs | 5 +++++
 tests/servers/udp/environment.rs  | 5 +++++
 5 files changed, 18 insertions(+)

diff --git a/src/bootstrap/app.rs b/src/bootstrap/app.rs
index ea7d7f030..ea5dc41b6 100644
--- a/src/bootstrap/app.rs
+++ b/src/bootstrap/app.rs
@@ -124,6 +124,7 @@ pub fn initialize_app_container(configuration: &Configuration) -> AppContainer {
     ));
 
     AppContainer {
+        database,
         tracker,
         keys_handler,
         authentication_service,
diff --git a/src/container.rs b/src/container.rs
index 14c4b5d7b..d8c95c42b 100644
--- a/src/container.rs
+++ b/src/container.rs
@@ -4,6 +4,7 @@ use tokio::sync::RwLock;
 
 use crate::core::authentication::handler::KeysHandler;
 use crate::core::authentication::service::AuthenticationService;
+use crate::core::databases::Database;
 use crate::core::statistics::event::sender::Sender;
 use crate::core::statistics::repository::Repository;
 use crate::core::whitelist::manager::WhiteListManager;
@@ -11,6 +12,7 @@ use crate::core::{whitelist, Tracker};
 use crate::servers::udp::server::banning::BanService;
 
 pub struct AppContainer {
+    pub database: Arc<Box<dyn Database>>,
     pub tracker: Arc<Tracker>,
     pub keys_handler: Arc<KeysHandler>,
     pub authentication_service: Arc<AuthenticationService>,
diff --git a/tests/servers/api/environment.rs b/tests/servers/api/environment.rs
index f014df36f..8967ff830 100644
--- a/tests/servers/api/environment.rs
+++ b/tests/servers/api/environment.rs
@@ -10,6 +10,7 @@ use torrust_tracker_lib::bootstrap::app::{initialize_app_container, initialize_g
 use torrust_tracker_lib::bootstrap::jobs::make_rust_tls;
 use torrust_tracker_lib::core::authentication::handler::KeysHandler;
 use torrust_tracker_lib::core::authentication::service::AuthenticationService;
+use torrust_tracker_lib::core::databases::Database;
 use torrust_tracker_lib::core::statistics::event::sender::Sender;
 use torrust_tracker_lib::core::statistics::repository::Repository;
 use torrust_tracker_lib::core::whitelist::manager::WhiteListManager;
@@ -24,6 +25,7 @@ where
     S: std::fmt::Debug + std::fmt::Display,
 {
     pub config: Arc<HttpApi>,
+    pub database: Arc<Box<dyn Database>>,
     pub tracker: Arc<Tracker>,
     pub keys_handler: Arc<KeysHandler>,
     pub authentication_service: Arc<AuthenticationService>,
@@ -61,6 +63,7 @@ impl Environment<Stopped> {
 
         Self {
             config,
+            database: app_container.database.clone(),
             tracker: app_container.tracker.clone(),
             keys_handler: app_container.keys_handler.clone(),
             authentication_service: app_container.authentication_service.clone(),
@@ -78,6 +81,7 @@ impl Environment<Stopped> {
 
         Environment {
             config: self.config,
+            database: self.database.clone(),
             tracker: self.tracker.clone(),
             keys_handler: self.keys_handler.clone(),
             authentication_service: self.authentication_service.clone(),
@@ -112,6 +116,7 @@ impl Environment<Running> {
     pub async fn stop(self) -> Environment<Stopped> {
         Environment {
             config: self.config,
+            database: self.database,
             tracker: self.tracker,
             keys_handler: self.keys_handler,
             authentication_service: self.authentication_service,
diff --git a/tests/servers/http/environment.rs b/tests/servers/http/environment.rs
index 81b6a12e2..80c042a21 100644
--- a/tests/servers/http/environment.rs
+++ b/tests/servers/http/environment.rs
@@ -7,6 +7,7 @@ use torrust_tracker_lib::bootstrap::app::{initialize_app_container, initialize_g
 use torrust_tracker_lib::bootstrap::jobs::make_rust_tls;
 use torrust_tracker_lib::core::authentication::handler::KeysHandler;
 use torrust_tracker_lib::core::authentication::service::AuthenticationService;
+use torrust_tracker_lib::core::databases::Database;
 use torrust_tracker_lib::core::statistics::event::sender::Sender;
 use torrust_tracker_lib::core::statistics::repository::Repository;
 use torrust_tracker_lib::core::whitelist::manager::WhiteListManager;
@@ -17,6 +18,7 @@ use torrust_tracker_primitives::peer;
 
 pub struct Environment<S> {
     pub config: Arc<HttpTracker>,
+    pub database: Arc<Box<dyn Database>>,
     pub tracker: Arc<Tracker>,
     pub keys_handler: Arc<KeysHandler>,
     pub authentication_service: Arc<AuthenticationService>,
@@ -57,6 +59,7 @@ impl Environment<Stopped> {
 
         Self {
             config,
+            database: app_container.database.clone(),
             tracker: app_container.tracker.clone(),
             keys_handler: app_container.keys_handler.clone(),
             authentication_service: app_container.authentication_service.clone(),
@@ -73,6 +76,7 @@ impl Environment<Stopped> {
     pub async fn start(self) -> Environment<Running> {
         Environment {
             config: self.config,
+            database: self.database.clone(),
             tracker: self.tracker.clone(),
             keys_handler: self.keys_handler.clone(),
             authentication_service: self.authentication_service.clone(),
@@ -104,6 +108,7 @@ impl Environment<Running> {
     pub async fn stop(self) -> Environment<Stopped> {
         Environment {
             config: self.config,
+            database: self.database,
             tracker: self.tracker,
             keys_handler: self.keys_handler,
             authentication_service: self.authentication_service,
diff --git a/tests/servers/udp/environment.rs b/tests/servers/udp/environment.rs
index b728509c0..c02e35e6e 100644
--- a/tests/servers/udp/environment.rs
+++ b/tests/servers/udp/environment.rs
@@ -5,6 +5,7 @@ use bittorrent_primitives::info_hash::InfoHash;
 use tokio::sync::RwLock;
 use torrust_tracker_configuration::{Configuration, UdpTracker, DEFAULT_TIMEOUT};
 use torrust_tracker_lib::bootstrap::app::{initialize_app_container, initialize_global_services};
+use torrust_tracker_lib::core::databases::Database;
 use torrust_tracker_lib::core::statistics::event::sender::Sender;
 use torrust_tracker_lib::core::statistics::repository::Repository;
 use torrust_tracker_lib::core::{whitelist, Tracker};
@@ -20,6 +21,7 @@ where
     S: std::fmt::Debug + std::fmt::Display,
 {
     pub config: Arc<UdpTracker>,
+    pub database: Arc<Box<dyn Database>>,
     pub tracker: Arc<Tracker>,
     pub whitelist_authorization: Arc<whitelist::authorization::Authorization>,
     pub stats_event_sender: Arc<Option<Box<dyn Sender>>>,
@@ -57,6 +59,7 @@ impl Environment<Stopped> {
 
         Self {
             config,
+            database: app_container.database.clone(),
             tracker: app_container.tracker.clone(),
             whitelist_authorization: app_container.whitelist_authorization.clone(),
             stats_event_sender: app_container.stats_event_sender.clone(),
@@ -72,6 +75,7 @@ impl Environment<Stopped> {
         let cookie_lifetime = self.config.cookie_lifetime;
         Environment {
             config: self.config,
+            database: self.database.clone(),
             tracker: self.tracker.clone(),
             whitelist_authorization: self.whitelist_authorization.clone(),
             stats_event_sender: self.stats_event_sender.clone(),
@@ -109,6 +113,7 @@ impl Environment<Running> {
 
         Environment {
             config: self.config,
+            database: self.database,
             tracker: self.tracker,
             whitelist_authorization: self.whitelist_authorization,
             stats_event_sender: self.stats_event_sender,

From b3fcdb4c156feb610ad719afca90ead8912f29db Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 18:11:47 +0000
Subject: [PATCH 09/11] refactor: [#1201] remove direct dependency on database
 from tracker

---
 src/bootstrap/app.rs                          |  1 -
 src/core/mod.rs                               | 26 ++-----------------
 src/core/services/mod.rs                      |  2 --
 src/core/services/statistics/mod.rs           |  3 +--
 src/core/services/torrent.rs                  |  6 ++---
 src/servers/http/v1/handlers/announce.rs      |  5 ++--
 src/servers/http/v1/handlers/scrape.rs        | 12 +++------
 src/servers/http/v1/services/announce.rs      |  6 ++---
 src/servers/http/v1/services/scrape.rs        |  6 ++---
 src/servers/udp/handlers.rs                   |  9 +++----
 tests/servers/api/mod.rs                      | 11 +++++---
 .../api/v1/contract/context/auth_key.rs       |  8 +++---
 .../api/v1/contract/context/whitelist.rs      |  6 ++---
 13 files changed, 32 insertions(+), 69 deletions(-)

diff --git a/src/bootstrap/app.rs b/src/bootstrap/app.rs
index ea5dc41b6..2340eb0ac 100644
--- a/src/bootstrap/app.rs
+++ b/src/bootstrap/app.rs
@@ -116,7 +116,6 @@ pub fn initialize_app_container(configuration: &Configuration) -> AppContainer {
 
     let tracker = Arc::new(initialize_tracker(
         configuration,
-        &database,
         &whitelist_authorization,
         &in_memory_torrent_repository,
         &db_torrent_repository,
diff --git a/src/core/mod.rs b/src/core/mod.rs
index a1b496c56..18c99d3b9 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -462,8 +462,6 @@ use torrust_tracker_primitives::peer;
 use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
 use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
 
-use crate::core::databases::Database;
-
 /// The domain layer tracker service.
 ///
 /// Its main responsibility is to handle the `announce` and `scrape` requests.
@@ -477,10 +475,6 @@ pub struct Tracker {
     /// The tracker configuration.
     config: Core,
 
-    /// A database driver implementation: [`Sqlite3`](crate::core::databases::sqlite)
-    /// or [`MySQL`](crate::core::databases::mysql)
-    database: Arc<Box<dyn Database>>,
-
     /// The service to check is a torrent is whitelisted.
     pub whitelist_authorization: Arc<whitelist::authorization::Authorization>,
 
@@ -544,7 +538,6 @@ impl Tracker {
     /// Will return a `databases::error::Error` if unable to connect to database. The `Tracker` is responsible for the persistence.
     pub fn new(
         config: &Core,
-        database: &Arc<Box<dyn Database>>,
         whitelist_authorization: &Arc<whitelist::authorization::Authorization>,
         in_memory_torrent_repository: &Arc<InMemoryTorrentRepository>,
         db_torrent_repository: &Arc<DatabasePersistentTorrentRepository>,
@@ -552,7 +545,6 @@ impl Tracker {
     ) -> Result<Tracker, databases::error::Error> {
         Ok(Tracker {
             config: config.clone(),
-            database: database.clone(),
             whitelist_authorization: whitelist_authorization.clone(),
             in_memory_torrent_repository: in_memory_torrent_repository.clone(),
             db_torrent_repository: db_torrent_repository.clone(),
@@ -739,17 +731,6 @@ impl Tracker {
     pub fn cleanup_torrents(&self) {
         self.torrents_manager.cleanup_torrents();
     }
-
-    /// It drops the database tables.
-    ///
-    /// # Errors
-    ///
-    /// Will return `Err` if unable to drop tables.
-    pub fn drop_database_tables(&self) -> Result<(), databases::error::Error> {
-        // todo: this is only used for testing. We have to pass the database
-        // reference directly to the tests instead of via the tracker.
-        self.database.drop_database_tables()
-    }
 }
 
 #[must_use]
@@ -787,7 +768,7 @@ mod tests {
             let config = configuration::ephemeral_public();
 
             let (
-                database,
+                _database,
                 _in_memory_whitelist,
                 whitelist_authorization,
                 _authentication_service,
@@ -798,7 +779,6 @@ mod tests {
 
             initialize_tracker(
                 &config,
-                &database,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
@@ -823,7 +803,6 @@ mod tests {
 
             let tracker = initialize_tracker(
                 &config,
-                &database,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
@@ -838,7 +817,7 @@ mod tests {
             config.core.tracker_policy.persistent_torrent_completed_stat = true;
 
             let (
-                database,
+                _database,
                 _in_memory_whitelist,
                 whitelist_authorization,
                 _authentication_service,
@@ -849,7 +828,6 @@ mod tests {
 
             initialize_tracker(
                 &config,
-                &database,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
diff --git a/src/core/services/mod.rs b/src/core/services/mod.rs
index f5d9bd375..3a684ac8f 100644
--- a/src/core/services/mod.rs
+++ b/src/core/services/mod.rs
@@ -31,7 +31,6 @@ use crate::core::Tracker;
 #[must_use]
 pub fn initialize_tracker(
     config: &Configuration,
-    database: &Arc<Box<dyn Database>>,
     whitelist_authorization: &Arc<whitelist::authorization::Authorization>,
     in_memory_torrent_repository: &Arc<InMemoryTorrentRepository>,
     db_torrent_repository: &Arc<DatabasePersistentTorrentRepository>,
@@ -39,7 +38,6 @@ pub fn initialize_tracker(
 ) -> Tracker {
     match Tracker::new(
         &Arc::new(config).core,
-        database,
         whitelist_authorization,
         in_memory_torrent_repository,
         db_torrent_repository,
diff --git a/src/core/services/statistics/mod.rs b/src/core/services/statistics/mod.rs
index 9e4696f48..01e49df71 100644
--- a/src/core/services/statistics/mod.rs
+++ b/src/core/services/statistics/mod.rs
@@ -133,7 +133,7 @@ mod tests {
         let config = tracker_configuration();
 
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             _authentication_service,
@@ -147,7 +147,6 @@ mod tests {
 
         let tracker = Arc::new(initialize_tracker(
             &config,
-            &database,
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
diff --git a/src/core/services/torrent.rs b/src/core/services/torrent.rs
index f8da88d6f..dc07405ee 100644
--- a/src/core/services/torrent.rs
+++ b/src/core/services/torrent.rs
@@ -119,7 +119,7 @@ mod tests {
 
     fn initialize_tracker_and_deps(config: &Configuration) -> Arc<Tracker> {
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             _authentication_service,
@@ -130,7 +130,6 @@ mod tests {
 
         Arc::new(initialize_tracker(
             config,
-            &database,
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
@@ -173,7 +172,7 @@ mod tests {
             let config = tracker_configuration();
 
             let (
-                database,
+                _database,
                 _in_memory_whitelist,
                 whitelist_authorization,
                 _authentication_service,
@@ -184,7 +183,6 @@ mod tests {
 
             let tracker = initialize_tracker(
                 &config,
-                &database,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
diff --git a/src/servers/http/v1/handlers/announce.rs b/src/servers/http/v1/handlers/announce.rs
index b0b54fa0d..4088ab73c 100644
--- a/src/servers/http/v1/handlers/announce.rs
+++ b/src/servers/http/v1/handlers/announce.rs
@@ -275,7 +275,7 @@ mod tests {
     /// Initialize tracker's dependencies and tracker.
     fn initialize_tracker_and_deps(config: &Configuration) -> TrackerAndDeps {
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             authentication_service,
@@ -283,13 +283,12 @@ mod tests {
             db_torrent_repository,
             torrents_manager,
         ) = initialize_tracker_dependencies(config);
-        
+
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
         let stats_event_sender = Arc::new(stats_event_sender);
 
         let tracker = Arc::new(initialize_tracker(
             config,
-            &database,
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
diff --git a/src/servers/http/v1/handlers/scrape.rs b/src/servers/http/v1/handlers/scrape.rs
index e619ba120..24b1c783d 100644
--- a/src/servers/http/v1/handlers/scrape.rs
+++ b/src/servers/http/v1/handlers/scrape.rs
@@ -152,7 +152,7 @@ mod tests {
         let config = configuration::ephemeral_private();
 
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             authentication_service,
@@ -166,7 +166,6 @@ mod tests {
         (
             initialize_tracker(
                 &config,
-                &database,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
@@ -185,7 +184,7 @@ mod tests {
         let config = configuration::ephemeral_listed();
 
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             authentication_service,
@@ -199,7 +198,6 @@ mod tests {
         (
             initialize_tracker(
                 &config,
-                &database,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
@@ -218,7 +216,7 @@ mod tests {
         let config = configuration::ephemeral_with_reverse_proxy();
 
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             authentication_service,
@@ -232,7 +230,6 @@ mod tests {
         (
             initialize_tracker(
                 &config,
-                &database,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
@@ -251,7 +248,7 @@ mod tests {
         let config = configuration::ephemeral_without_reverse_proxy();
 
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             authentication_service,
@@ -265,7 +262,6 @@ mod tests {
         (
             initialize_tracker(
                 &config,
-                &database,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
diff --git a/src/servers/http/v1/services/announce.rs b/src/servers/http/v1/services/announce.rs
index 99724f728..56b2dd1e3 100644
--- a/src/servers/http/v1/services/announce.rs
+++ b/src/servers/http/v1/services/announce.rs
@@ -74,7 +74,7 @@ mod tests {
         let config = configuration::ephemeral_public();
 
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             _authentication_service,
@@ -87,7 +87,6 @@ mod tests {
 
         let tracker = initialize_tracker(
             &config,
-            &database,
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
@@ -147,7 +146,7 @@ mod tests {
             let config = configuration::ephemeral();
 
             let (
-                database,
+                _database,
                 _in_memory_whitelist,
                 whitelist_authorization,
                 _authentication_service,
@@ -158,7 +157,6 @@ mod tests {
 
             Tracker::new(
                 &config.core,
-                &database,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
diff --git a/src/servers/http/v1/services/scrape.rs b/src/servers/http/v1/services/scrape.rs
index c9e657d11..ea4cb2702 100644
--- a/src/servers/http/v1/services/scrape.rs
+++ b/src/servers/http/v1/services/scrape.rs
@@ -88,7 +88,7 @@ mod tests {
         let config = configuration::ephemeral_public();
 
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             _authentication_service,
@@ -99,7 +99,6 @@ mod tests {
 
         initialize_tracker(
             &config,
-            &database,
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
@@ -131,7 +130,7 @@ mod tests {
         let config = configuration::ephemeral();
 
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             _authentication_service,
@@ -142,7 +141,6 @@ mod tests {
 
         Tracker::new(
             &config.core,
-            &database,
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs
index 6abbd95c6..c85efc1fa 100644
--- a/src/servers/udp/handlers.rs
+++ b/src/servers/udp/handlers.rs
@@ -525,14 +525,13 @@ mod tests {
             db_torrent_repository,
             torrents_manager,
         ) = initialize_tracker_dependencies(config);
-        
+
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
         let stats_event_sender = Arc::new(stats_event_sender);
         let whitelist_manager = initialize_whitelist_manager(database.clone(), in_memory_whitelist.clone());
 
         let tracker = Arc::new(initialize_tracker(
             config,
-            &database,
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
@@ -646,7 +645,7 @@ mod tests {
         let config = tracker_configuration();
 
         let (
-            database,
+            _database,
             _in_memory_whitelist,
             whitelist_authorization,
             _authentication_service,
@@ -658,7 +657,6 @@ mod tests {
         let tracker = Arc::new(
             Tracker::new(
                 &config.core,
-                &database,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
@@ -1411,7 +1409,7 @@ mod tests {
                     let config = Arc::new(TrackerConfigurationBuilder::default().with_external_ip("::126.0.0.1").into());
 
                     let (
-                        database,
+                        _database,
                         _in_memory_whitelist,
                         whitelist_authorization,
                         _authentication_service,
@@ -1432,7 +1430,6 @@ mod tests {
                     let tracker = Arc::new(
                         core::Tracker::new(
                             &config.core,
-                            &database,
                             &whitelist_authorization,
                             &in_memory_torrent_repository,
                             &db_torrent_repository,
diff --git a/tests/servers/api/mod.rs b/tests/servers/api/mod.rs
index 278fd869d..92bc19a5f 100644
--- a/tests/servers/api/mod.rs
+++ b/tests/servers/api/mod.rs
@@ -1,6 +1,6 @@
 use std::sync::Arc;
 
-use torrust_tracker_lib::core::Tracker;
+use torrust_tracker_lib::core::databases::Database;
 use torrust_tracker_lib::servers::apis::server;
 
 pub mod connection_info;
@@ -9,12 +9,15 @@ pub mod v1;
 
 pub type Started = environment::Environment<server::Running>;
 
-/// It forces a database error by dropping all tables.
-/// That makes any query fail.
+/// It forces a database error by dropping all tables. That makes all queries
+/// fail.
+///
 /// code-review:
+///
 /// Alternatively we could:
+///
 /// - Inject a database mock in the future.
 /// - Inject directly the database reference passed to the Tracker type.
-pub fn force_database_error(tracker: &Arc<Tracker>) {
+pub fn force_database_error(tracker: &Arc<Box<dyn Database>>) {
     tracker.drop_database_tables().unwrap();
 }
diff --git a/tests/servers/api/v1/contract/context/auth_key.rs b/tests/servers/api/v1/contract/context/auth_key.rs
index 73860c9c2..3b7d2d6ba 100644
--- a/tests/servers/api/v1/contract/context/auth_key.rs
+++ b/tests/servers/api/v1/contract/context/auth_key.rs
@@ -126,7 +126,7 @@ async fn should_fail_when_the_auth_key_cannot_be_generated() {
 
     let env = Started::new(&configuration::ephemeral().into()).await;
 
-    force_database_error(&env.tracker);
+    force_database_error(&env.database);
 
     let request_id = Uuid::new_v4();
 
@@ -297,7 +297,7 @@ async fn should_fail_when_the_auth_key_cannot_be_deleted() {
         .await
         .unwrap();
 
-    force_database_error(&env.tracker);
+    force_database_error(&env.database);
 
     let request_id = Uuid::new_v4();
 
@@ -403,7 +403,7 @@ async fn should_fail_when_keys_cannot_be_reloaded() {
         .await
         .unwrap();
 
-    force_database_error(&env.tracker);
+    force_database_error(&env.database);
 
     let response = Client::new(env.get_connection_info())
         .reload_keys(Some(headers_with_request_id(request_id)))
@@ -556,7 +556,7 @@ mod deprecated_generate_key_endpoint {
 
         let env = Started::new(&configuration::ephemeral().into()).await;
 
-        force_database_error(&env.tracker);
+        force_database_error(&env.database);
 
         let request_id = Uuid::new_v4();
         let seconds_valid = 60;
diff --git a/tests/servers/api/v1/contract/context/whitelist.rs b/tests/servers/api/v1/contract/context/whitelist.rs
index aef1db4f1..78850d3bf 100644
--- a/tests/servers/api/v1/contract/context/whitelist.rs
+++ b/tests/servers/api/v1/contract/context/whitelist.rs
@@ -111,7 +111,7 @@ async fn should_fail_when_the_torrent_cannot_be_whitelisted() {
 
     let info_hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned();
 
-    force_database_error(&env.tracker);
+    force_database_error(&env.database);
 
     let request_id = Uuid::new_v4();
 
@@ -239,7 +239,7 @@ async fn should_fail_when_the_torrent_cannot_be_removed_from_the_whitelist() {
     let info_hash = InfoHash::from_str(&hash).unwrap();
     env.whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap();
 
-    force_database_error(&env.tracker);
+    force_database_error(&env.database);
 
     let request_id = Uuid::new_v4();
 
@@ -340,7 +340,7 @@ async fn should_fail_when_the_whitelist_cannot_be_reloaded_from_the_database() {
     let info_hash = InfoHash::from_str(&hash).unwrap();
     env.whitelist_manager.add_torrent_to_whitelist(&info_hash).await.unwrap();
 
-    force_database_error(&env.tracker);
+    force_database_error(&env.database);
 
     let request_id = Uuid::new_v4();
 

From 3a2e8f0d4c3a1d06d77fd83b7f2d065f250e8390 Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 18:17:37 +0000
Subject: [PATCH 10/11] refactor: [#1201] reorganize methods in tracker

Grouping similar methods.
---
 src/core/mod.rs | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/core/mod.rs b/src/core/mod.rs
index 18c99d3b9..d50d2b545 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -653,28 +653,6 @@ impl Tracker {
         scrape_data
     }
 
-    /// It returns the data for a `scrape` response.
-    fn get_swarm_metadata(&self, info_hash: &InfoHash) -> SwarmMetadata {
-        self.in_memory_torrent_repository.get_swarm_metadata(info_hash)
-    }
-
-    /// # Context: Tracker
-    ///
-    /// Get torrent peers for a given torrent and client.
-    ///
-    /// It filters out the client making the request.
-    fn get_peers_for(&self, info_hash: &InfoHash, peer: &peer::Peer, limit: usize) -> Vec<Arc<peer::Peer>> {
-        self.in_memory_torrent_repository.get_peers_for(info_hash, peer, limit)
-    }
-
-    /// # Context: Tracker
-    ///
-    /// Get torrent peers for a given torrent.
-    #[must_use]
-    pub fn get_torrent_peers(&self, info_hash: &InfoHash) -> Vec<Arc<peer::Peer>> {
-        self.in_memory_torrent_repository.get_torrent_peers(info_hash)
-    }
-
     /// It updates the torrent entry in memory, it also stores in the database
     /// the torrent info data which is persistent, and finally return the data
     /// needed for a `announce` request response.
@@ -713,6 +691,28 @@ impl Tracker {
         }
     }
 
+    /// It returns the data for a `scrape` response.
+    fn get_swarm_metadata(&self, info_hash: &InfoHash) -> SwarmMetadata {
+        self.in_memory_torrent_repository.get_swarm_metadata(info_hash)
+    }
+
+    /// # Context: Tracker
+    ///
+    /// Get torrent peers for a given torrent and client.
+    ///
+    /// It filters out the client making the request.
+    fn get_peers_for(&self, info_hash: &InfoHash, peer: &peer::Peer, limit: usize) -> Vec<Arc<peer::Peer>> {
+        self.in_memory_torrent_repository.get_peers_for(info_hash, peer, limit)
+    }
+
+    /// # Context: Tracker
+    ///
+    /// Get torrent peers for a given torrent.
+    #[must_use]
+    pub fn get_torrent_peers(&self, info_hash: &InfoHash) -> Vec<Arc<peer::Peer>> {
+        self.in_memory_torrent_repository.get_torrent_peers(info_hash)
+    }
+
     /// It calculates and returns the general `Tracker`
     /// [`TorrentsMetrics`]
     ///

From 612f7293d5a2190e710852dfd51330248e50c61a Mon Sep 17 00:00:00 2001
From: Jose Celano <josecelano@gmail.com>
Date: Thu, 23 Jan 2025 18:28:16 +0000
Subject: [PATCH 11/11] refactor: [#1201] remove tracker dependency on
 TorrentsManager

---
 src/app.rs                               |  2 +-
 src/bootstrap/app.rs                     |  4 ++-
 src/bootstrap/jobs/torrent_cleanup.rs    | 12 ++++-----
 src/container.rs                         |  6 +++++
 src/core/mod.rs                          | 33 +++++++-----------------
 src/core/services/mod.rs                 |  3 ---
 src/core/services/statistics/mod.rs      |  3 +--
 src/core/services/torrent.rs             |  6 ++---
 src/servers/http/v1/handlers/announce.rs |  3 +--
 src/servers/http/v1/handlers/scrape.rs   | 12 +++------
 src/servers/http/v1/services/announce.rs |  6 ++---
 src/servers/http/v1/services/scrape.rs   |  6 ++---
 src/servers/udp/handlers.rs              |  9 +++----
 13 files changed, 41 insertions(+), 64 deletions(-)

diff --git a/src/app.rs b/src/app.rs
index e41f227e7..c71237443 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -137,7 +137,7 @@ pub async fn start(config: &Configuration, app_container: &AppContainer) -> Vec<
 
     // Start runners to remove torrents without peers, every interval
     if config.core.inactive_peer_cleanup_interval > 0 {
-        jobs.push(torrent_cleanup::start_job(&config.core, &app_container.tracker));
+        jobs.push(torrent_cleanup::start_job(&config.core, &app_container.torrents_manager));
     }
 
     // Start Health Check API
diff --git a/src/bootstrap/app.rs b/src/bootstrap/app.rs
index 2340eb0ac..294b2ca73 100644
--- a/src/bootstrap/app.rs
+++ b/src/bootstrap/app.rs
@@ -119,7 +119,6 @@ pub fn initialize_app_container(configuration: &Configuration) -> AppContainer {
         &whitelist_authorization,
         &in_memory_torrent_repository,
         &db_torrent_repository,
-        &torrents_manager,
     ));
 
     AppContainer {
@@ -132,6 +131,9 @@ pub fn initialize_app_container(configuration: &Configuration) -> AppContainer {
         stats_event_sender,
         stats_repository,
         whitelist_manager,
+        in_memory_torrent_repository,
+        db_torrent_repository,
+        torrents_manager,
     }
 }
 
diff --git a/src/bootstrap/jobs/torrent_cleanup.rs b/src/bootstrap/jobs/torrent_cleanup.rs
index 6abb4f26b..45e6e9e68 100644
--- a/src/bootstrap/jobs/torrent_cleanup.rs
+++ b/src/bootstrap/jobs/torrent_cleanup.rs
@@ -17,7 +17,7 @@ use tokio::task::JoinHandle;
 use torrust_tracker_configuration::Core;
 use tracing::instrument;
 
-use crate::core;
+use crate::core::torrent::manager::TorrentsManager;
 
 /// It starts a jobs for cleaning up the torrent data in the tracker.
 ///
@@ -25,9 +25,9 @@ use crate::core;
 ///
 /// Refer to [`torrust-tracker-configuration documentation`](https://docs.rs/torrust-tracker-configuration) for more info about that option.
 #[must_use]
-#[instrument(skip(config, tracker))]
-pub fn start_job(config: &Core, tracker: &Arc<core::Tracker>) -> JoinHandle<()> {
-    let weak_tracker = std::sync::Arc::downgrade(tracker);
+#[instrument(skip(config, torrents_manager))]
+pub fn start_job(config: &Core, torrents_manager: &Arc<TorrentsManager>) -> JoinHandle<()> {
+    let weak_torrents_manager = std::sync::Arc::downgrade(torrents_manager);
     let interval = config.inactive_peer_cleanup_interval;
 
     tokio::spawn(async move {
@@ -42,10 +42,10 @@ pub fn start_job(config: &Core, tracker: &Arc<core::Tracker>) -> JoinHandle<()>
                     break;
                 }
                 _ = interval.tick() => {
-                    if let Some(tracker) = weak_tracker.upgrade() {
+                    if let Some(torrents_manager) = weak_torrents_manager.upgrade() {
                         let start_time = Utc::now().time();
                         tracing::info!("Cleaning up torrents..");
-                        tracker.cleanup_torrents();
+                        torrents_manager.cleanup_torrents();
                         tracing::info!("Cleaned up torrents in: {}ms", (Utc::now().time() - start_time).num_milliseconds());
                     } else {
                         break;
diff --git a/src/container.rs b/src/container.rs
index d8c95c42b..8407d0b69 100644
--- a/src/container.rs
+++ b/src/container.rs
@@ -7,6 +7,9 @@ use crate::core::authentication::service::AuthenticationService;
 use crate::core::databases::Database;
 use crate::core::statistics::event::sender::Sender;
 use crate::core::statistics::repository::Repository;
+use crate::core::torrent::manager::TorrentsManager;
+use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository;
+use crate::core::torrent::repository::persisted::DatabasePersistentTorrentRepository;
 use crate::core::whitelist::manager::WhiteListManager;
 use crate::core::{whitelist, Tracker};
 use crate::servers::udp::server::banning::BanService;
@@ -21,4 +24,7 @@ pub struct AppContainer {
     pub stats_event_sender: Arc<Option<Box<dyn Sender>>>,
     pub stats_repository: Arc<Repository>,
     pub whitelist_manager: Arc<WhiteListManager>,
+    pub in_memory_torrent_repository: Arc<InMemoryTorrentRepository>,
+    pub db_torrent_repository: Arc<DatabasePersistentTorrentRepository>,
+    pub torrents_manager: Arc<TorrentsManager>,
 }
diff --git a/src/core/mod.rs b/src/core/mod.rs
index d50d2b545..f2483b21e 100644
--- a/src/core/mod.rs
+++ b/src/core/mod.rs
@@ -453,7 +453,6 @@ use std::net::IpAddr;
 use std::sync::Arc;
 
 use bittorrent_primitives::info_hash::InfoHash;
-use torrent::manager::TorrentsManager;
 use torrent::repository::in_memory::InMemoryTorrentRepository;
 use torrent::repository::persisted::DatabasePersistentTorrentRepository;
 use torrust_tracker_configuration::{AnnouncePolicy, Core, TORRENT_PEERS_LIMIT};
@@ -483,9 +482,6 @@ pub struct Tracker {
 
     /// The persistent torrents repository.
     db_torrent_repository: Arc<DatabasePersistentTorrentRepository>,
-
-    /// The service to run torrents tasks.
-    torrents_manager: Arc<TorrentsManager>,
 }
 
 /// How many peers the peer announcing wants in the announce response.
@@ -541,14 +537,12 @@ impl Tracker {
         whitelist_authorization: &Arc<whitelist::authorization::Authorization>,
         in_memory_torrent_repository: &Arc<InMemoryTorrentRepository>,
         db_torrent_repository: &Arc<DatabasePersistentTorrentRepository>,
-        torrents_manager: &Arc<TorrentsManager>,
     ) -> Result<Tracker, databases::error::Error> {
         Ok(Tracker {
             config: config.clone(),
             whitelist_authorization: whitelist_authorization.clone(),
             in_memory_torrent_repository: in_memory_torrent_repository.clone(),
             db_torrent_repository: db_torrent_repository.clone(),
-            torrents_manager: torrents_manager.clone(),
         })
     }
 
@@ -724,13 +718,6 @@ impl Tracker {
     pub fn get_torrents_metrics(&self) -> TorrentsMetrics {
         self.in_memory_torrent_repository.get_torrents_metrics()
     }
-
-    /// Remove inactive peers and (optionally) peerless torrents.
-    ///
-    /// # Context: Tracker
-    pub fn cleanup_torrents(&self) {
-        self.torrents_manager.cleanup_torrents();
-    }
 }
 
 #[must_use]
@@ -761,6 +748,7 @@ mod tests {
         use crate::app_test::initialize_tracker_dependencies;
         use crate::core::peer::Peer;
         use crate::core::services::{initialize_tracker, initialize_whitelist_manager};
+        use crate::core::torrent::manager::TorrentsManager;
         use crate::core::whitelist::manager::WhiteListManager;
         use crate::core::{whitelist, TorrentsMetrics, Tracker};
 
@@ -774,7 +762,7 @@ mod tests {
                 _authentication_service,
                 in_memory_torrent_repository,
                 db_torrent_repository,
-                torrents_manager,
+                _torrents_manager,
             ) = initialize_tracker_dependencies(&config);
 
             initialize_tracker(
@@ -782,7 +770,6 @@ mod tests {
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
-                &torrents_manager,
             )
         }
 
@@ -796,7 +783,7 @@ mod tests {
                 _authentication_service,
                 in_memory_torrent_repository,
                 db_torrent_repository,
-                torrents_manager,
+                _torrents_manager,
             ) = initialize_tracker_dependencies(&config);
 
             let whitelist_manager = initialize_whitelist_manager(database.clone(), in_memory_whitelist.clone());
@@ -806,13 +793,12 @@ mod tests {
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
-                &torrents_manager,
             );
 
             (tracker, whitelist_authorization, whitelist_manager)
         }
 
-        pub fn tracker_persisting_torrents_in_database() -> Tracker {
+        pub fn tracker_persisting_torrents_in_database() -> (Tracker, Arc<TorrentsManager>) {
             let mut config = configuration::ephemeral_listed();
             config.core.tracker_policy.persistent_torrent_completed_stat = true;
 
@@ -826,13 +812,14 @@ mod tests {
                 torrents_manager,
             ) = initialize_tracker_dependencies(&config);
 
-            initialize_tracker(
+            let tracker = initialize_tracker(
                 &config,
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
-                &torrents_manager,
-            )
+            );
+
+            (tracker, torrents_manager)
         }
 
         fn sample_info_hash() -> InfoHash {
@@ -1492,7 +1479,7 @@ mod tests {
 
             #[tokio::test]
             async fn it_should_persist_the_number_of_completed_peers_for_all_torrents_into_the_database() {
-                let tracker = tracker_persisting_torrents_in_database();
+                let (tracker, torrents_manager) = tracker_persisting_torrents_in_database();
 
                 let info_hash = sample_info_hash();
 
@@ -1509,7 +1496,7 @@ mod tests {
                 // Remove the newly updated torrent from memory
                 let _unused = tracker.in_memory_torrent_repository.remove(&info_hash);
 
-                tracker.torrents_manager.load_torrents_from_database().unwrap();
+                torrents_manager.load_torrents_from_database().unwrap();
 
                 let torrent_entry = tracker
                     .in_memory_torrent_repository
diff --git a/src/core/services/mod.rs b/src/core/services/mod.rs
index 3a684ac8f..a9bca2df7 100644
--- a/src/core/services/mod.rs
+++ b/src/core/services/mod.rs
@@ -14,7 +14,6 @@ use torrust_tracker_configuration::v2_0_0::database;
 use torrust_tracker_configuration::Configuration;
 
 use super::databases::{self, Database};
-use super::torrent::manager::TorrentsManager;
 use super::torrent::repository::in_memory::InMemoryTorrentRepository;
 use super::torrent::repository::persisted::DatabasePersistentTorrentRepository;
 use super::whitelist;
@@ -34,14 +33,12 @@ pub fn initialize_tracker(
     whitelist_authorization: &Arc<whitelist::authorization::Authorization>,
     in_memory_torrent_repository: &Arc<InMemoryTorrentRepository>,
     db_torrent_repository: &Arc<DatabasePersistentTorrentRepository>,
-    torrents_manager: &Arc<TorrentsManager>,
 ) -> Tracker {
     match Tracker::new(
         &Arc::new(config).core,
         whitelist_authorization,
         in_memory_torrent_repository,
         db_torrent_repository,
-        torrents_manager,
     ) {
         Ok(tracker) => tracker,
         Err(error) => {
diff --git a/src/core/services/statistics/mod.rs b/src/core/services/statistics/mod.rs
index 01e49df71..7c2233efd 100644
--- a/src/core/services/statistics/mod.rs
+++ b/src/core/services/statistics/mod.rs
@@ -139,7 +139,7 @@ mod tests {
             _authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(&config);
 
         let (_stats_event_sender, stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
@@ -150,7 +150,6 @@ mod tests {
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
-            &torrents_manager,
         ));
 
         let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP)));
diff --git a/src/core/services/torrent.rs b/src/core/services/torrent.rs
index dc07405ee..c2ffa05aa 100644
--- a/src/core/services/torrent.rs
+++ b/src/core/services/torrent.rs
@@ -125,7 +125,7 @@ mod tests {
             _authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(config);
 
         Arc::new(initialize_tracker(
@@ -133,7 +133,6 @@ mod tests {
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
-            &torrents_manager,
         ))
     }
 
@@ -178,7 +177,7 @@ mod tests {
                 _authentication_service,
                 in_memory_torrent_repository,
                 db_torrent_repository,
-                torrents_manager,
+                _torrents_manager,
             ) = initialize_tracker_dependencies(&config);
 
             let tracker = initialize_tracker(
@@ -186,7 +185,6 @@ mod tests {
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
-                &torrents_manager,
             );
 
             let tracker = Arc::new(tracker);
diff --git a/src/servers/http/v1/handlers/announce.rs b/src/servers/http/v1/handlers/announce.rs
index 4088ab73c..a9567fb81 100644
--- a/src/servers/http/v1/handlers/announce.rs
+++ b/src/servers/http/v1/handlers/announce.rs
@@ -281,7 +281,7 @@ mod tests {
             authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(config);
 
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
@@ -292,7 +292,6 @@ mod tests {
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
-            &torrents_manager,
         ));
 
         (tracker, stats_event_sender, whitelist_authorization, authentication_service)
diff --git a/src/servers/http/v1/handlers/scrape.rs b/src/servers/http/v1/handlers/scrape.rs
index 24b1c783d..116d717a1 100644
--- a/src/servers/http/v1/handlers/scrape.rs
+++ b/src/servers/http/v1/handlers/scrape.rs
@@ -158,7 +158,7 @@ mod tests {
             authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(&config);
 
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
@@ -169,7 +169,6 @@ mod tests {
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
-                &torrents_manager,
             ),
             stats_event_sender,
             authentication_service,
@@ -190,7 +189,7 @@ mod tests {
             authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(&config);
 
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
@@ -201,7 +200,6 @@ mod tests {
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
-                &torrents_manager,
             ),
             stats_event_sender,
             authentication_service,
@@ -222,7 +220,7 @@ mod tests {
             authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(&config);
 
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
@@ -233,7 +231,6 @@ mod tests {
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
-                &torrents_manager,
             ),
             stats_event_sender,
             authentication_service,
@@ -254,7 +251,7 @@ mod tests {
             authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(&config);
 
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
@@ -265,7 +262,6 @@ mod tests {
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
-                &torrents_manager,
             ),
             stats_event_sender,
             authentication_service,
diff --git a/src/servers/http/v1/services/announce.rs b/src/servers/http/v1/services/announce.rs
index 56b2dd1e3..322bc80eb 100644
--- a/src/servers/http/v1/services/announce.rs
+++ b/src/servers/http/v1/services/announce.rs
@@ -80,7 +80,7 @@ mod tests {
             _authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(&config);
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
         let stats_event_sender = Arc::new(stats_event_sender);
@@ -90,7 +90,6 @@ mod tests {
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
-            &torrents_manager,
         );
 
         (tracker, stats_event_sender)
@@ -152,7 +151,7 @@ mod tests {
                 _authentication_service,
                 in_memory_torrent_repository,
                 db_torrent_repository,
-                torrents_manager,
+                _torrents_manager,
             ) = initialize_tracker_dependencies(&config);
 
             Tracker::new(
@@ -160,7 +159,6 @@ mod tests {
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
-                &torrents_manager,
             )
             .unwrap()
         }
diff --git a/src/servers/http/v1/services/scrape.rs b/src/servers/http/v1/services/scrape.rs
index ea4cb2702..299938f84 100644
--- a/src/servers/http/v1/services/scrape.rs
+++ b/src/servers/http/v1/services/scrape.rs
@@ -94,7 +94,7 @@ mod tests {
             _authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(&config);
 
         initialize_tracker(
@@ -102,7 +102,6 @@ mod tests {
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
-            &torrents_manager,
         )
     }
 
@@ -136,7 +135,7 @@ mod tests {
             _authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(&config);
 
         Tracker::new(
@@ -144,7 +143,6 @@ mod tests {
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
-            &torrents_manager,
         )
         .unwrap()
     }
diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs
index c85efc1fa..5584c167b 100644
--- a/src/servers/udp/handlers.rs
+++ b/src/servers/udp/handlers.rs
@@ -523,7 +523,7 @@ mod tests {
             _authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(config);
 
         let (stats_event_sender, _stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);
@@ -535,7 +535,6 @@ mod tests {
             &whitelist_authorization,
             &in_memory_torrent_repository,
             &db_torrent_repository,
-            &torrents_manager,
         ));
 
         (
@@ -651,7 +650,7 @@ mod tests {
             _authentication_service,
             in_memory_torrent_repository,
             db_torrent_repository,
-            torrents_manager,
+            _torrents_manager,
         ) = initialize_tracker_dependencies(&config);
 
         let tracker = Arc::new(
@@ -660,7 +659,6 @@ mod tests {
                 &whitelist_authorization,
                 &in_memory_torrent_repository,
                 &db_torrent_repository,
-                &torrents_manager,
             )
             .unwrap(),
         );
@@ -1415,7 +1413,7 @@ mod tests {
                         _authentication_service,
                         in_memory_torrent_repository,
                         db_torrent_repository,
-                        torrents_manager,
+                        _torrents_manager,
                     ) = initialize_tracker_dependencies(&config);
 
                     let mut stats_event_sender_mock = statistics::event::sender::MockSender::new();
@@ -1433,7 +1431,6 @@ mod tests {
                             &whitelist_authorization,
                             &in_memory_torrent_repository,
                             &db_torrent_repository,
-                            &torrents_manager,
                         )
                         .unwrap(),
                     );