Skip to content

Commit 5ee9efb

Browse files
committed
Merge #1503: Overhaul stats: fix bug in downloads counter
32a37d1 fix: [#1502] bug in total number of downloads for all torrents metric (Jose Celano) Pull request description: Relates to: #1502 Revert the change that introduced a bug in [this commit](34c159a). Issue #1502 has been partially implemented. - Bug fixed. - Unit tests added to avoid regression. In a future PR, I will implement a change to avoid keeping the swarms in memory just to track the number of downloads for that torrent. ACKs for top commit: josecelano: ACK 32a37d1 Tree-SHA512: 41f1e9fe60d61fcfeca45463e9b2fc24a15edf83681337df5724ce3b0628f10031977e08dd414b7880560e170c08c958c3e21c10b4afcc4707018f5d017b6778
2 parents 3adbb89 + 32a37d1 commit 5ee9efb

File tree

1 file changed

+102
-20
lines changed

1 file changed

+102
-20
lines changed

packages/torrent-repository/src/swarm.rs

Lines changed: 102 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,20 @@ impl Swarm {
191191
}
192192

193193
/// Returns true if the swarm meets the retention policy, meaning that
194-
/// it should be kept in the tracker.
194+
/// it should be kept in the list of swarms.
195195
#[must_use]
196196
pub fn meets_retaining_policy(&self, policy: &TrackerPolicy) -> bool {
197-
!(policy.remove_peerless_torrents && self.is_empty())
197+
!self.should_be_removed(policy)
198+
}
199+
200+
fn should_be_removed(&self, policy: &TrackerPolicy) -> bool {
201+
// If the policy is to remove peerless torrents and the swarm is empty (no peers),
202+
(policy.remove_peerless_torrents && self.is_empty())
203+
// but not when the policy is to persist torrent stats and the
204+
// torrent has been downloaded at least once.
205+
// (because the only way to store the counter is to keep the swarm in memory.
206+
// See https://github.com/torrust/torrust-tracker/issues/1502)
207+
&& !(policy.persistent_torrent_completed_stat && self.metadata().downloaded > 0)
198208
}
199209
}
200210

@@ -205,7 +215,6 @@ mod tests {
205215
use std::sync::Arc;
206216

207217
use aquatic_udp_protocol::PeerId;
208-
use torrust_tracker_configuration::TrackerPolicy;
209218
use torrust_tracker_primitives::peer::fixture::PeerBuilder;
210219
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
211220
use torrust_tracker_primitives::DurationSinceUnixEpoch;
@@ -376,28 +385,101 @@ mod tests {
376385
assert_eq!(swarm.len(), 1);
377386
}
378387

379-
#[test]
380-
fn it_should_be_kept_when_empty_if_the_tracker_policy_is_not_to_remove_peerless_torrents() {
381-
let empty_swarm = Swarm::default();
388+
mod for_retaining_policy {
382389

383-
let policy = TrackerPolicy {
384-
remove_peerless_torrents: false,
385-
..Default::default()
386-
};
390+
use torrust_tracker_configuration::TrackerPolicy;
391+
use torrust_tracker_primitives::peer::fixture::PeerBuilder;
387392

388-
assert!(empty_swarm.meets_retaining_policy(&policy));
389-
}
393+
use crate::Swarm;
390394

391-
#[test]
392-
fn it_should_be_removed_when_empty_if_the_tracker_policy_is_to_remove_peerless_torrents() {
393-
let empty_swarm = Swarm::default();
395+
fn empty_swarm() -> Swarm {
396+
Swarm::default()
397+
}
394398

395-
let policy = TrackerPolicy {
396-
remove_peerless_torrents: true,
397-
..Default::default()
398-
};
399+
fn not_empty_swarm() -> Swarm {
400+
let mut swarm = Swarm::default();
401+
swarm.upsert_peer(PeerBuilder::default().build().into(), &mut false);
402+
swarm
403+
}
404+
405+
fn not_empty_swarm_with_downloads() -> Swarm {
406+
let mut swarm = Swarm::default();
407+
408+
let mut peer = PeerBuilder::leecher().build();
409+
let mut downloads_increased = false;
410+
411+
swarm.upsert_peer(peer.into(), &mut downloads_increased);
412+
413+
peer.event = aquatic_udp_protocol::AnnounceEvent::Completed;
414+
415+
swarm.upsert_peer(peer.into(), &mut downloads_increased);
416+
417+
assert!(swarm.metadata().downloads() > 0);
418+
419+
swarm
420+
}
421+
422+
fn remove_peerless_torrents_policy() -> TrackerPolicy {
423+
TrackerPolicy {
424+
remove_peerless_torrents: true,
425+
..Default::default()
426+
}
427+
}
428+
429+
fn don_not_remove_peerless_torrents_policy() -> TrackerPolicy {
430+
TrackerPolicy {
431+
remove_peerless_torrents: false,
432+
..Default::default()
433+
}
434+
}
399435

400-
assert!(!empty_swarm.meets_retaining_policy(&policy));
436+
mod when_removing_peerless_torrents_is_enabled {
437+
438+
use torrust_tracker_configuration::TrackerPolicy;
439+
440+
use crate::swarm::tests::for_retaining_policy::{
441+
empty_swarm, not_empty_swarm, not_empty_swarm_with_downloads, remove_peerless_torrents_policy,
442+
};
443+
444+
#[test]
445+
fn it_should_be_removed_if_the_swarm_is_empty() {
446+
assert!(empty_swarm().should_be_removed(&remove_peerless_torrents_policy()));
447+
}
448+
449+
#[test]
450+
fn it_should_not_be_removed_is_the_swarm_is_not_empty() {
451+
assert!(!not_empty_swarm().should_be_removed(&remove_peerless_torrents_policy()));
452+
}
453+
454+
#[test]
455+
fn it_should_not_be_removed_even_if_the_swarm_is_empty_if_we_need_to_track_stats_for_downloads_and_there_has_been_downloads(
456+
) {
457+
let policy = TrackerPolicy {
458+
remove_peerless_torrents: true,
459+
persistent_torrent_completed_stat: true,
460+
..Default::default()
461+
};
462+
463+
assert!(!not_empty_swarm_with_downloads().should_be_removed(&policy));
464+
}
465+
}
466+
467+
mod when_removing_peerless_torrents_is_disabled {
468+
469+
use crate::swarm::tests::for_retaining_policy::{
470+
don_not_remove_peerless_torrents_policy, empty_swarm, not_empty_swarm,
471+
};
472+
473+
#[test]
474+
fn it_should_not_be_removed_even_if_the_swarm_is_empty() {
475+
assert!(!empty_swarm().should_be_removed(&don_not_remove_peerless_torrents_policy()));
476+
}
477+
478+
#[test]
479+
fn it_should_not_be_removed_is_the_swarm_is_not_empty() {
480+
assert!(!not_empty_swarm().should_be_removed(&don_not_remove_peerless_torrents_policy()));
481+
}
482+
}
401483
}
402484

403485
#[test]

0 commit comments

Comments
 (0)