Skip to content

Commit 8f67f12

Browse files
committedMar 5, 2025··
fix: [#1264] partially. The correct number of downloads is persited
However, we still have to load the value counter from the database the first time the otrrent is added to the repository.
1 parent 6beec3a commit 8f67f12

File tree

5 files changed

+56
-41
lines changed

5 files changed

+56
-41
lines changed
 

‎packages/tracker-core/src/announce_handler.rs

+14-31
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ use bittorrent_primitives::info_hash::InfoHash;
9797
use torrust_tracker_configuration::{Core, TORRENT_PEERS_LIMIT};
9898
use torrust_tracker_primitives::core::AnnounceData;
9999
use torrust_tracker_primitives::peer;
100-
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
101100

102101
use super::torrent::repository::in_memory::InMemoryTorrentRepository;
103102
use super::torrent::repository::persisted::DatabasePersistentTorrentRepository;
@@ -164,45 +163,29 @@ impl AnnounceHandler {
164163
) -> Result<AnnounceData, AnnounceError> {
165164
self.whitelist_authorization.authorize(info_hash).await?;
166165

167-
tracing::debug!("Before: {peer:?}");
168166
peer.change_ip(&assign_ip_address_to_peer(remote_client_ip, self.config.net.external_ip));
169-
tracing::debug!("After: {peer:?}");
170167

171-
let stats = self.upsert_peer_and_get_stats(info_hash, peer);
172-
173-
let peers = self
174-
.in_memory_torrent_repository
175-
.get_peers_for(info_hash, peer, peers_wanted.limit());
176-
177-
Ok(AnnounceData {
178-
peers,
179-
stats,
180-
policy: self.config.announce_policy,
181-
})
182-
}
183-
184-
/// Updates the torrent data in memory, persists statistics if needed, and
185-
/// returns the updated swarm stats.
186-
#[must_use]
187-
fn upsert_peer_and_get_stats(&self, info_hash: &InfoHash, peer: &peer::Peer) -> SwarmMetadata {
188168
let number_of_downloads_increased = self.in_memory_torrent_repository.upsert_peer(info_hash, peer);
189169

190-
let swarm_metadata = self.in_memory_torrent_repository.get_swarm_metadata(info_hash);
191-
192-
if number_of_downloads_increased {
193-
self.persist_stats(info_hash, &swarm_metadata);
170+
if self.config.tracker_policy.persistent_torrent_completed_stat && number_of_downloads_increased {
171+
self.db_torrent_repository.increase_number_of_downloads(info_hash)?;
194172
}
195173

196-
swarm_metadata
174+
Ok(self.build_announce_data(info_hash, peer, peers_wanted))
197175
}
198176

199-
/// Persists torrent statistics to the database if persistence is enabled.
200-
fn persist_stats(&self, info_hash: &InfoHash, swarm_metadata: &SwarmMetadata) {
201-
if self.config.tracker_policy.persistent_torrent_completed_stat {
202-
let completed = swarm_metadata.downloaded;
203-
let info_hash = *info_hash;
177+
/// Builds the announce data for the peer making the request.
178+
fn build_announce_data(&self, info_hash: &InfoHash, peer: &peer::Peer, peers_wanted: &PeersWanted) -> AnnounceData {
179+
let peers = self
180+
.in_memory_torrent_repository
181+
.get_peers_for(info_hash, peer, peers_wanted.limit());
204182

205-
drop(self.db_torrent_repository.save(&info_hash, completed));
183+
let swarm_metadata = self.in_memory_torrent_repository.get_swarm_metadata(info_hash);
184+
185+
AnnounceData {
186+
peers,
187+
stats: swarm_metadata,
188+
policy: self.config.announce_policy,
206189
}
207190
}
208191
}

‎packages/tracker-core/src/databases/driver/sqlite.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -164,19 +164,12 @@ impl Database for Sqlite {
164164
fn increase_number_of_downloads(&self, info_hash: &InfoHash) -> Result<(), Error> {
165165
let conn = self.pool.get().map_err(|e| (e, DRIVER))?;
166166

167-
let update = conn.execute(
167+
let _ = conn.execute(
168168
"UPDATE torrents SET completed = completed + 1 WHERE info_hash = ?",
169169
[info_hash.to_string()],
170170
)?;
171171

172-
if update == 0 {
173-
Err(Error::UpdateFailed {
174-
location: Location::caller(),
175-
driver: DRIVER,
176-
})
177-
} else {
178-
Ok(())
179-
}
172+
Ok(())
180173
}
181174

182175
/// Refer to [`databases::Database::load_keys`](crate::core::databases::Database::load_keys).

‎packages/tracker-core/src/databases/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ pub trait Database: Sync + Send {
128128

129129
/// Increases the number of downloads for a given torrent.
130130
///
131+
/// It does not create a new entry if the torrent is not found and it does
132+
/// not return an error.
133+
///
131134
/// # Arguments
132135
///
133136
/// * `info_hash` - A reference to the torrent's info hash.

‎packages/tracker-core/src/error.rs

+4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ pub enum AnnounceError {
6666
/// Wraps errors related to torrent whitelisting.
6767
#[error("Whitelist error: {0}")]
6868
Whitelist(#[from] WhitelistError),
69+
70+
/// Wraps errors related to database.
71+
#[error("Database error: {0}")]
72+
Database(#[from] databases::error::Error),
6973
}
7074

7175
/// Errors related to scrape requests.

‎packages/tracker-core/src/torrent/repository/persisted.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,26 @@ impl DatabasePersistentTorrentRepository {
4747
}
4848
}
4949

50+
/// Increases the number of downloads for a given torrent.
51+
///
52+
/// If the torrent is not found, it creates a new entry.
53+
///
54+
/// # Arguments
55+
///
56+
/// * `info_hash` - The info hash of the torrent.
57+
///
58+
/// # Errors
59+
///
60+
/// Returns an [`Error`] if the database operation fails.
61+
pub(crate) fn increase_number_of_downloads(&self, info_hash: &InfoHash) -> Result<(), Error> {
62+
let torrent = self.load(info_hash)?;
63+
64+
match torrent {
65+
Some(_number_of_downloads) => self.database.increase_number_of_downloads(info_hash),
66+
None => self.save(info_hash, 1),
67+
}
68+
}
69+
5070
/// Loads all persistent torrent metrics from the database.
5171
///
5272
/// This function retrieves the torrent metrics (e.g., download counts) from the persistent store
@@ -67,7 +87,6 @@ impl DatabasePersistentTorrentRepository {
6787
/// # Errors
6888
///
6989
/// Returns an [`Error`] if the underlying database query fails.
70-
#[allow(dead_code)]
7190
pub(crate) fn load(&self, info_hash: &InfoHash) -> Result<Option<PersistentTorrent>, Error> {
7291
self.database.load_persistent_torrent(info_hash)
7392
}
@@ -118,6 +137,19 @@ mod tests {
118137
assert_eq!(torrents.get(&infohash), Some(1).as_ref());
119138
}
120139

140+
#[test]
141+
fn it_increases_the_numbers_of_downloads_for_a_torrent_into_the_database() {
142+
let repository = initialize_db_persistent_torrent_repository();
143+
144+
let infohash = sample_info_hash();
145+
146+
repository.increase_number_of_downloads(&infohash).unwrap();
147+
148+
let torrents = repository.load_all().unwrap();
149+
150+
assert_eq!(torrents.get(&infohash), Some(1).as_ref());
151+
}
152+
121153
#[test]
122154
fn it_loads_the_numbers_of_downloads_for_all_torrents_from_the_database() {
123155
let repository = initialize_db_persistent_torrent_repository();

0 commit comments

Comments
 (0)
Please sign in to comment.