Skip to content

Commit 06ef1d5

Browse files
committed
fix: [#1264] number of downloads preset when torrent is persisted
This fixed a bug: the number of donwloads for a torrent is not loaded from the database when the torrent is added to the in-memory torrent repository. It should be done when stats are enabled with the configuration option: persistent_torrent_completed_stat = true The patch is applied only to the torrent repository implementation we are using in prodcution (`CrossbeamSkipList<EntryMutexStd>`). The other implementations have this comment: ``` // todo: load persistent torrent data if provided ``` It was not implemented for the others becuase I'm considering taking the counter (for the number of downloads) out of the in-memory repository. And increase it by suing events triggered from the core tracker. I will open a new issue for that. If that's implemented we will need to remove this patch for the repository, meaning reverting cahnges in this commit.
1 parent 8f67f12 commit 06ef1d5

File tree

22 files changed

+197
-94
lines changed

22 files changed

+197
-94
lines changed

packages/axum-http-tracker-server/src/environment.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl<S> Environment<S> {
2626
.container
2727
.tracker_core_container
2828
.in_memory_torrent_repository
29-
.upsert_peer(info_hash, peer);
29+
.upsert_peer(info_hash, peer, None);
3030
}
3131
}
3232

packages/axum-rest-tracker-api-server/src/environment.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ where
3737
.container
3838
.tracker_core_container
3939
.in_memory_torrent_repository
40-
.upsert_peer(info_hash, peer);
40+
.upsert_peer(info_hash, peer, None);
4141
}
4242
}
4343

packages/torrent-repository/benches/helpers/asyn.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ where
1818

1919
let info_hash = InfoHash::default();
2020

21-
torrent_repository.upsert_peer(&info_hash, &DEFAULT_PEER).await;
21+
torrent_repository.upsert_peer(&info_hash, &DEFAULT_PEER, None).await;
2222

2323
torrent_repository.get_swarm_metadata(&info_hash).await;
2424
}
@@ -37,7 +37,7 @@ where
3737
let handles = FuturesUnordered::new();
3838

3939
// Add the torrent/peer to the torrent repository
40-
torrent_repository.upsert_peer(&info_hash, &DEFAULT_PEER).await;
40+
torrent_repository.upsert_peer(&info_hash, &DEFAULT_PEER, None).await;
4141

4242
torrent_repository.get_swarm_metadata(&info_hash).await;
4343

@@ -47,7 +47,7 @@ where
4747
let torrent_repository_clone = torrent_repository.clone();
4848

4949
let handle = runtime.spawn(async move {
50-
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER).await;
50+
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER, None).await;
5151

5252
torrent_repository_clone.get_swarm_metadata(&info_hash).await;
5353

@@ -87,7 +87,7 @@ where
8787
let torrent_repository_clone = torrent_repository.clone();
8888

8989
let handle = runtime.spawn(async move {
90-
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER).await;
90+
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER, None).await;
9191

9292
torrent_repository_clone.get_swarm_metadata(&info_hash).await;
9393

@@ -123,7 +123,7 @@ where
123123

124124
// Add the torrents/peers to the torrent repository
125125
for info_hash in &info_hashes {
126-
torrent_repository.upsert_peer(info_hash, &DEFAULT_PEER).await;
126+
torrent_repository.upsert_peer(info_hash, &DEFAULT_PEER, None).await;
127127
torrent_repository.get_swarm_metadata(info_hash).await;
128128
}
129129

@@ -133,7 +133,7 @@ where
133133
let torrent_repository_clone = torrent_repository.clone();
134134

135135
let handle = runtime.spawn(async move {
136-
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER).await;
136+
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER, None).await;
137137
torrent_repository_clone.get_swarm_metadata(&info_hash).await;
138138

139139
if let Some(sleep_time) = sleep {

packages/torrent-repository/benches/helpers/sync.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ where
2020

2121
let info_hash = InfoHash::default();
2222

23-
torrent_repository.upsert_peer(&info_hash, &DEFAULT_PEER);
23+
torrent_repository.upsert_peer(&info_hash, &DEFAULT_PEER, None);
2424

2525
torrent_repository.get_swarm_metadata(&info_hash);
2626
}
@@ -39,7 +39,7 @@ where
3939
let handles = FuturesUnordered::new();
4040

4141
// Add the torrent/peer to the torrent repository
42-
torrent_repository.upsert_peer(&info_hash, &DEFAULT_PEER);
42+
torrent_repository.upsert_peer(&info_hash, &DEFAULT_PEER, None);
4343

4444
torrent_repository.get_swarm_metadata(&info_hash);
4545

@@ -49,7 +49,7 @@ where
4949
let torrent_repository_clone = torrent_repository.clone();
5050

5151
let handle = runtime.spawn(async move {
52-
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER);
52+
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER, None);
5353

5454
torrent_repository_clone.get_swarm_metadata(&info_hash);
5555

@@ -89,7 +89,7 @@ where
8989
let torrent_repository_clone = torrent_repository.clone();
9090

9191
let handle = runtime.spawn(async move {
92-
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER);
92+
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER, None);
9393

9494
torrent_repository_clone.get_swarm_metadata(&info_hash);
9595

@@ -125,7 +125,7 @@ where
125125

126126
// Add the torrents/peers to the torrent repository
127127
for info_hash in &info_hashes {
128-
torrent_repository.upsert_peer(info_hash, &DEFAULT_PEER);
128+
torrent_repository.upsert_peer(info_hash, &DEFAULT_PEER, None);
129129
torrent_repository.get_swarm_metadata(info_hash);
130130
}
131131

@@ -135,7 +135,7 @@ where
135135
let torrent_repository_clone = torrent_repository.clone();
136136

137137
let handle = runtime.spawn(async move {
138-
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER);
138+
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER, None);
139139
torrent_repository_clone.get_swarm_metadata(&info_hash);
140140

141141
if let Some(sleep_time) = sleep {

packages/torrent-repository/src/repository/dash_map_mutex_std.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use torrust_tracker_configuration::TrackerPolicy;
66
use torrust_tracker_primitives::pagination::Pagination;
77
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
88
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
9-
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
9+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent, PersistentTorrents};
1010

1111
use super::Repository;
1212
use crate::entry::peer_list::PeerList;
@@ -23,7 +23,9 @@ where
2323
EntryMutexStd: EntrySync,
2424
EntrySingle: Entry,
2525
{
26-
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
26+
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer, _opt_persistent_torrent: Option<PersistentTorrent>) -> bool {
27+
// todo: load persistent torrent data if provided
28+
2729
if let Some(entry) = self.torrents.get(info_hash) {
2830
entry.upsert_peer(peer)
2931
} else {

packages/torrent-repository/src/repository/mod.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use torrust_tracker_configuration::TrackerPolicy;
33
use torrust_tracker_primitives::pagination::Pagination;
44
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
55
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
6-
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
6+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent, PersistentTorrents};
77

88
pub mod dash_map_mutex_std;
99
pub mod rw_lock_std;
@@ -24,7 +24,7 @@ pub trait Repository<T>: Debug + Default + Sized + 'static {
2424
fn remove(&self, key: &InfoHash) -> Option<T>;
2525
fn remove_inactive_peers(&self, current_cutoff: DurationSinceUnixEpoch);
2626
fn remove_peerless_torrents(&self, policy: &TrackerPolicy);
27-
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool;
27+
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer, opt_persistent_torrent: Option<PersistentTorrent>) -> bool;
2828
fn get_swarm_metadata(&self, info_hash: &InfoHash) -> Option<SwarmMetadata>;
2929
}
3030

@@ -37,6 +37,11 @@ pub trait RepositoryAsync<T>: Debug + Default + Sized + 'static {
3737
fn remove(&self, key: &InfoHash) -> impl std::future::Future<Output = Option<T>> + Send;
3838
fn remove_inactive_peers(&self, current_cutoff: DurationSinceUnixEpoch) -> impl std::future::Future<Output = ()> + Send;
3939
fn remove_peerless_torrents(&self, policy: &TrackerPolicy) -> impl std::future::Future<Output = ()> + Send;
40-
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> impl std::future::Future<Output = bool> + Send;
40+
fn upsert_peer(
41+
&self,
42+
info_hash: &InfoHash,
43+
peer: &peer::Peer,
44+
opt_persistent_torrent: Option<PersistentTorrent>,
45+
) -> impl std::future::Future<Output = bool> + Send;
4146
fn get_swarm_metadata(&self, info_hash: &InfoHash) -> impl std::future::Future<Output = Option<SwarmMetadata>> + Send;
4247
}

packages/torrent-repository/src/repository/rw_lock_std.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use torrust_tracker_configuration::TrackerPolicy;
33
use torrust_tracker_primitives::pagination::Pagination;
44
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
55
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
6-
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
6+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent, PersistentTorrents};
77

88
use super::Repository;
99
use crate::entry::peer_list::PeerList;
@@ -46,7 +46,9 @@ impl Repository<EntrySingle> for TorrentsRwLockStd
4646
where
4747
EntrySingle: Entry,
4848
{
49-
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
49+
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer, _opt_persistent_torrent: Option<PersistentTorrent>) -> bool {
50+
// todo: load persistent torrent data if provided
51+
5052
let mut db = self.get_torrents_mut();
5153

5254
let entry = db.entry(*info_hash).or_insert(EntrySingle::default());

packages/torrent-repository/src/repository/rw_lock_std_mutex_std.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use torrust_tracker_configuration::TrackerPolicy;
55
use torrust_tracker_primitives::pagination::Pagination;
66
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
77
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
8-
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
8+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent, PersistentTorrents};
99

1010
use super::Repository;
1111
use crate::entry::peer_list::PeerList;
@@ -33,7 +33,9 @@ where
3333
EntryMutexStd: EntrySync,
3434
EntrySingle: Entry,
3535
{
36-
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
36+
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer, _opt_persistent_torrent: Option<PersistentTorrent>) -> bool {
37+
// todo: load persistent torrent data if provided
38+
3739
let maybe_entry = self.get_torrents().get(info_hash).cloned();
3840

3941
let entry = if let Some(entry) = maybe_entry {

packages/torrent-repository/src/repository/rw_lock_std_mutex_tokio.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use torrust_tracker_configuration::TrackerPolicy;
99
use torrust_tracker_primitives::pagination::Pagination;
1010
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
1111
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
12-
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
12+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent, PersistentTorrents};
1313

1414
use super::RepositoryAsync;
1515
use crate::entry::peer_list::PeerList;
@@ -37,7 +37,14 @@ where
3737
EntryMutexTokio: EntryAsync,
3838
EntrySingle: Entry,
3939
{
40-
async fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
40+
async fn upsert_peer(
41+
&self,
42+
info_hash: &InfoHash,
43+
peer: &peer::Peer,
44+
_opt_persistent_torrent: Option<PersistentTorrent>,
45+
) -> bool {
46+
// todo: load persistent torrent data if provided
47+
4148
let maybe_entry = self.get_torrents().get(info_hash).cloned();
4249

4350
let entry = if let Some(entry) = maybe_entry {

packages/torrent-repository/src/repository/rw_lock_tokio.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use torrust_tracker_configuration::TrackerPolicy;
33
use torrust_tracker_primitives::pagination::Pagination;
44
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
55
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
6-
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
6+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent, PersistentTorrents};
77

88
use super::RepositoryAsync;
99
use crate::entry::peer_list::PeerList;
@@ -47,7 +47,14 @@ impl RepositoryAsync<EntrySingle> for TorrentsRwLockTokio
4747
where
4848
EntrySingle: Entry,
4949
{
50-
async fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
50+
async fn upsert_peer(
51+
&self,
52+
info_hash: &InfoHash,
53+
peer: &peer::Peer,
54+
_opt_persistent_torrent: Option<PersistentTorrent>,
55+
) -> bool {
56+
// todo: load persistent torrent data if provided
57+
5158
let mut db = self.get_torrents_mut().await;
5259

5360
let entry = db.entry(*info_hash).or_insert(EntrySingle::default());

packages/torrent-repository/src/repository/rw_lock_tokio_mutex_std.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use torrust_tracker_configuration::TrackerPolicy;
55
use torrust_tracker_primitives::pagination::Pagination;
66
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
77
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
8-
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
8+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent, PersistentTorrents};
99

1010
use super::RepositoryAsync;
1111
use crate::entry::peer_list::PeerList;
@@ -35,7 +35,14 @@ where
3535
EntryMutexStd: EntrySync,
3636
EntrySingle: Entry,
3737
{
38-
async fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
38+
async fn upsert_peer(
39+
&self,
40+
info_hash: &InfoHash,
41+
peer: &peer::Peer,
42+
_opt_persistent_torrent: Option<PersistentTorrent>,
43+
) -> bool {
44+
// todo: load persistent torrent data if provided
45+
3946
let maybe_entry = self.get_torrents().await.get(info_hash).cloned();
4047

4148
let entry = if let Some(entry) = maybe_entry {

packages/torrent-repository/src/repository/rw_lock_tokio_mutex_tokio.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use torrust_tracker_configuration::TrackerPolicy;
55
use torrust_tracker_primitives::pagination::Pagination;
66
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
77
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
8-
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
8+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent, PersistentTorrents};
99

1010
use super::RepositoryAsync;
1111
use crate::entry::peer_list::PeerList;
@@ -35,7 +35,14 @@ where
3535
EntryMutexTokio: EntryAsync,
3636
EntrySingle: Entry,
3737
{
38-
async fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
38+
async fn upsert_peer(
39+
&self,
40+
info_hash: &InfoHash,
41+
peer: &peer::Peer,
42+
_opt_persistent_torrent: Option<PersistentTorrent>,
43+
) -> bool {
44+
// todo: load persistent torrent data if provided
45+
3946
let maybe_entry = self.get_torrents().await.get(info_hash).cloned();
4047

4148
let entry = if let Some(entry) = maybe_entry {

packages/torrent-repository/src/repository/skip_map_mutex_std.rs

+43-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use torrust_tracker_configuration::TrackerPolicy;
66
use torrust_tracker_primitives::pagination::Pagination;
77
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
88
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
9-
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
9+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrent, PersistentTorrents};
1010

1111
use super::Repository;
1212
use crate::entry::peer_list::PeerList;
@@ -23,9 +23,42 @@ where
2323
EntryMutexStd: EntrySync,
2424
EntrySingle: Entry,
2525
{
26-
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
27-
let entry = self.torrents.get_or_insert(*info_hash, Arc::default());
28-
entry.value().upsert_peer(peer)
26+
/// Upsert a peer into the swarm of a torrent.
27+
///
28+
/// Optionally, it can also preset the number of downloads of the torrent
29+
/// only if it's the first time the torrent is being inserted.
30+
///
31+
/// # Arguments
32+
///
33+
/// * `info_hash` - The info hash of the torrent.
34+
/// * `peer` - The peer to upsert.
35+
/// * `opt_persistent_torrent` - The optional persisted data about a torrent
36+
/// (number of downloads for the torrent).
37+
///
38+
/// # Returns
39+
///
40+
/// Returns `true` if the number of downloads was increased because the peer
41+
/// completed the download.
42+
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer, opt_persistent_torrent: Option<PersistentTorrent>) -> bool {
43+
if let Some(existing_entry) = self.torrents.get(info_hash) {
44+
existing_entry.value().upsert_peer(peer)
45+
} else {
46+
let new_entry = if let Some(number_of_downloads) = opt_persistent_torrent {
47+
EntryMutexStd::new(
48+
EntrySingle {
49+
swarm: PeerList::default(),
50+
downloaded: number_of_downloads,
51+
}
52+
.into(),
53+
)
54+
} else {
55+
EntryMutexStd::default()
56+
};
57+
58+
let inserted_entry = self.torrents.get_or_insert(*info_hash, new_entry);
59+
60+
inserted_entry.value().upsert_peer(peer)
61+
}
2962
}
3063

3164
fn get_swarm_metadata(&self, info_hash: &InfoHash) -> Option<SwarmMetadata> {
@@ -114,7 +147,9 @@ where
114147
EntryRwLockParkingLot: EntrySync,
115148
EntrySingle: Entry,
116149
{
117-
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
150+
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer, _opt_persistent_torrent: Option<PersistentTorrent>) -> bool {
151+
// todo: load persistent torrent data if provided
152+
118153
let entry = self.torrents.get_or_insert(*info_hash, Arc::default());
119154
entry.value().upsert_peer(peer)
120155
}
@@ -205,7 +240,9 @@ where
205240
EntryMutexParkingLot: EntrySync,
206241
EntrySingle: Entry,
207242
{
208-
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
243+
fn upsert_peer(&self, info_hash: &InfoHash, peer: &peer::Peer, _opt_persistent_torrent: Option<PersistentTorrent>) -> bool {
244+
// todo: load persistent torrent data if provided
245+
209246
let entry = self.torrents.get_or_insert(*info_hash, Arc::default());
210247
entry.value().upsert_peer(peer)
211248
}

0 commit comments

Comments
 (0)