Skip to content

Commit

Permalink
refactor: extract struct SwarmStats
Browse files Browse the repository at this point in the history
(da2ce7): Merge `SwarmStats` into `SwarmMetadata`.
  • Loading branch information
josecelano authored and da2ce7 committed Jan 12, 2024
1 parent d4adfa7 commit 58a57d3
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 74 deletions.
2 changes: 1 addition & 1 deletion packages/configuration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ pub struct HealthCheckApi {
}

/// Announce policy
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, Copy)]
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub struct AnnouncePolicy {
/// Interval in seconds that the client should wait between sending regular
/// announce requests to the tracker.
Expand Down
12 changes: 6 additions & 6 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ impl Tracker {
let (stats, stats_updated) = self.torrents.update_torrent_with_peer_and_get_stats(info_hash, peer).await;

if self.config.persistent_torrent_completed_stat && stats_updated {
let completed = stats.completed;
let completed = stats.downloaded;
let info_hash = *info_hash;

drop(self.database.save_persistent_torrent(&info_hash, completed).await);
Expand Down Expand Up @@ -1390,7 +1390,7 @@ mod tests {

let announce_data = tracker.announce(&sample_info_hash(), &mut peer, &peer_ip()).await;

assert_eq!(announce_data.swarm_stats.seeders, 1);
assert_eq!(announce_data.swarm_stats.complete, 1);
}

#[tokio::test]
Expand All @@ -1401,7 +1401,7 @@ mod tests {

let announce_data = tracker.announce(&sample_info_hash(), &mut peer, &peer_ip()).await;

assert_eq!(announce_data.swarm_stats.leechers, 1);
assert_eq!(announce_data.swarm_stats.incomplete, 1);
}

#[tokio::test]
Expand All @@ -1415,7 +1415,7 @@ mod tests {
let mut completed_peer = completed_peer();
let announce_data = tracker.announce(&sample_info_hash(), &mut completed_peer, &peer_ip()).await;

assert_eq!(announce_data.swarm_stats.completed, 1);
assert_eq!(announce_data.swarm_stats.downloaded, 1);
}
}
}
Expand Down Expand Up @@ -1739,11 +1739,11 @@ mod tests {

peer.event = AnnounceEvent::Started;
let swarm_stats = tracker.update_torrent_with_peer_and_get_stats(&info_hash, &peer).await;
assert_eq!(swarm_stats.completed, 0);
assert_eq!(swarm_stats.downloaded, 0);

peer.event = AnnounceEvent::Completed;
let swarm_stats = tracker.update_torrent_with_peer_and_get_stats(&info_hash, &peer).await;
assert_eq!(swarm_stats.completed, 1);
assert_eq!(swarm_stats.downloaded, 1);

// Remove the newly updated torrent from memory
tracker.torrents.get_torrents_mut().await.remove(&info_hash);
Expand Down
14 changes: 2 additions & 12 deletions src/core/torrent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,8 @@ impl SwarmMetadata {
}
}

/// Swarm statistics for one torrent.
///
/// See [BEP 48: Tracker Protocol Extension: Scrape](https://www.bittorrent.org/beps/bep_0048.html)
#[derive(Debug, PartialEq, Default)]
pub struct SwarmStats {
/// The number of peers that have ever completed downloading
pub completed: u32,
/// The number of active peers that have completed downloading (seeders)
pub seeders: u32,
/// The number of active peers that have not completed downloading (leechers)
pub leechers: u32,
}
/// [`SwarmStats`] has the same form as [`SwarmMetadata`]
pub type SwarmStats = SwarmMetadata;

impl Entry {
#[must_use]
Expand Down
30 changes: 15 additions & 15 deletions src/core/torrent/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ impl Repository for Sync {

(
SwarmStats {
completed: stats.1,
seeders: stats.0,
leechers: stats.2,
downloaded: stats.1,
complete: stats.0,
incomplete: stats.2,
},
stats_updated,
)
Expand Down Expand Up @@ -131,9 +131,9 @@ impl Repository for SyncSingle {

(
SwarmStats {
completed: stats.1,
seeders: stats.0,
leechers: stats.2,
downloaded: stats.1,
complete: stats.0,
incomplete: stats.2,
},
stats_updated,
)
Expand Down Expand Up @@ -176,9 +176,9 @@ impl TRepositoryAsync for RepositoryAsync {

(
SwarmStats {
completed: stats.1,
seeders: stats.0,
leechers: stats.2,
downloaded: stats.1,
complete: stats.0,
incomplete: stats.2,
},
stats_updated,
)
Expand Down Expand Up @@ -234,9 +234,9 @@ impl TRepositoryAsync for AsyncSync {

(
SwarmStats {
completed: stats.1,
seeders: stats.0,
leechers: stats.2,
downloaded: stats.1,
complete: stats.0,
incomplete: stats.2,
},
stats_updated,
)
Expand Down Expand Up @@ -281,9 +281,9 @@ impl TRepositoryAsync for RepositoryAsyncSingle {

(
SwarmStats {
completed: stats.1,
seeders: stats.0,
leechers: stats.2,
downloaded: stats.1,
complete: stats.0,
incomplete: stats.2,
},
stats_updated,
)
Expand Down
77 changes: 44 additions & 33 deletions src/servers/http/v1/responses/announce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use std::panic::Location;

use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use serde::{self, Deserialize, Serialize};
use thiserror::Error;
use torrust_tracker_configuration::AnnouncePolicy;
use torrust_tracker_contrib_bencode::{ben_bytes, ben_int, ben_list, ben_map, BMutAccess, BencodeMut};

use crate::core::torrent::SwarmStats;
use crate::core::{self, AnnounceData};
use crate::servers::http::v1::responses;

Expand All @@ -22,15 +22,19 @@ use crate::servers::http::v1::responses;
/// ```rust
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
/// use torrust_tracker_configuration::AnnouncePolicy;
/// use torrust_tracker::core::torrent::SwarmStats;
/// use torrust_tracker::servers::http::v1::responses::announce::{Normal, NormalPeer};
///
/// let response = Normal {
/// policy: AnnouncePolicy {
/// interval: 111,
/// interval_min: 222,
/// },
/// complete: 333,
/// incomplete: 444,
/// stats: SwarmStats {
/// downloaded: 0,
/// complete: 333,
/// incomplete: 444,
/// },
/// peers: vec![
/// // IPV4
/// NormalPeer {
Expand Down Expand Up @@ -60,15 +64,10 @@ use crate::servers::http::v1::responses;
///
/// Refer to [BEP 03: The `BitTorrent` Protocol Specification](https://www.bittorrent.org/beps/bep_0003.html)
/// for more information.
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[derive(Debug, PartialEq)]
pub struct Normal {
/// Announce policy
pub policy: AnnouncePolicy,
/// Number of peers with the entire file, i.e. seeders.
pub complete: u32,
/// Number of non-seeder peers, aka "leechers".
pub incomplete: u32,
/// A list of peers. The value is a list of dictionaries.
pub stats: SwarmStats,
pub peers: Vec<NormalPeer>,
}

Expand All @@ -85,7 +84,7 @@ pub struct Normal {
/// port: 0x7070, // 28784
/// };
/// ```
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[derive(Debug, PartialEq)]
pub struct NormalPeer {
/// The peer's ID.
pub peer_id: [u8; 20],
Expand Down Expand Up @@ -131,8 +130,8 @@ impl Normal {
}

(ben_map! {
"complete" => ben_int!(i64::from(self.complete)),
"incomplete" => ben_int!(i64::from(self.incomplete)),
"complete" => ben_int!(i64::from(self.stats.complete)),
"incomplete" => ben_int!(i64::from(self.stats.incomplete)),
"interval" => ben_int!(i64::from(self.policy.interval)),
"min interval" => ben_int!(i64::from(self.policy.interval_min)),
"peers" => peers_list.clone()
Expand Down Expand Up @@ -160,8 +159,11 @@ impl From<AnnounceData> for Normal {
interval: domain_announce_response.interval,
interval_min: domain_announce_response.interval_min,
},
complete: domain_announce_response.swarm_stats.seeders,
incomplete: domain_announce_response.swarm_stats.leechers,
stats: SwarmStats {
complete: domain_announce_response.swarm_stats.complete,
incomplete: domain_announce_response.swarm_stats.incomplete,
downloaded: 0,
},
peers,
}
}
Expand All @@ -176,15 +178,19 @@ impl From<AnnounceData> for Normal {
/// ```rust
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
/// use torrust_tracker_configuration::AnnouncePolicy;
/// use torrust_tracker::core::torrent::SwarmStats;
/// use torrust_tracker::servers::http::v1::responses::announce::{Compact, CompactPeer};
///
/// let response = Compact {
/// policy: AnnouncePolicy {
/// interval: 111,
/// interval_min: 222,
/// },
/// complete: 333,
/// incomplete: 444,
/// stats: SwarmStats {
/// downloaded: 0,
/// complete: 333,
/// incomplete: 444,
/// },
/// peers: vec![
/// // IPV4
/// CompactPeer {
Expand Down Expand Up @@ -216,15 +222,10 @@ impl From<AnnounceData> for Normal {
///
/// - [BEP 23: Tracker Returns Compact Peer Lists](https://www.bittorrent.org/beps/bep_0023.html)
/// - [BEP 07: IPv6 Tracker Extension](https://www.bittorrent.org/beps/bep_0007.html)
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[derive(Debug, PartialEq)]
pub struct Compact {
/// Announce policy
pub policy: AnnouncePolicy,
/// Number of seeders, aka "completed".
pub complete: u32,
/// Number of non-seeder peers, aka "incomplete".
pub incomplete: u32,
/// Compact peer list.
pub stats: SwarmStats,
pub peers: Vec<CompactPeer>,
}

Expand All @@ -250,7 +251,7 @@ pub struct Compact {
///
/// Refer to [BEP 23: Tracker Returns Compact Peer Lists](https://www.bittorrent.org/beps/bep_0023.html)
/// for more information.
#[derive(Serialize, Deserialize, Debug, PartialEq)]
#[derive(Debug, PartialEq)]
pub struct CompactPeer {
/// The peer's IP address.
pub ip: IpAddr,
Expand Down Expand Up @@ -296,8 +297,8 @@ impl Compact {
/// Will return `Err` if internally interrupted.
pub fn body(&self) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let bytes = (ben_map! {
"complete" => ben_int!(i64::from(self.complete)),
"incomplete" => ben_int!(i64::from(self.incomplete)),
"complete" => ben_int!(i64::from(self.stats.complete)),
"incomplete" => ben_int!(i64::from(self.stats.incomplete)),
"interval" => ben_int!(i64::from(self.policy.interval)),
"min interval" => ben_int!(i64::from(self.policy.interval_min)),
"peers" => ben_bytes!(self.peers_v4_bytes()?),
Expand Down Expand Up @@ -381,8 +382,11 @@ impl From<AnnounceData> for Compact {
interval: domain_announce_response.interval,
interval_min: domain_announce_response.interval_min,
},
complete: domain_announce_response.swarm_stats.seeders,
incomplete: domain_announce_response.swarm_stats.leechers,
stats: SwarmStats {
complete: domain_announce_response.swarm_stats.complete,
incomplete: domain_announce_response.swarm_stats.incomplete,
downloaded: 0,
},
peers,
}
}
Expand All @@ -396,6 +400,7 @@ mod tests {
use torrust_tracker_configuration::AnnouncePolicy;

use super::{Normal, NormalPeer};
use crate::core::torrent::SwarmStats;
use crate::servers::http::v1::responses::announce::{Compact, CompactPeer};

// Some ascii values used in tests:
Expand All @@ -417,8 +422,11 @@ mod tests {
interval: 111,
interval_min: 222,
},
complete: 333,
incomplete: 444,
stats: SwarmStats {
downloaded: 0,
complete: 333,
incomplete: 444,
},
peers: vec![
// IPV4
NormalPeer {
Expand Down Expand Up @@ -453,8 +461,11 @@ mod tests {
interval: 111,
interval_min: 222,
},
complete: 333,
incomplete: 444,
stats: SwarmStats {
downloaded: 0,
complete: 333,
incomplete: 444,
},
peers: vec![
// IPV4
CompactPeer {
Expand Down
6 changes: 3 additions & 3 deletions src/servers/http/v1/services/announce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ mod tests {
let expected_announce_data = AnnounceData {
peers: vec![],
swarm_stats: SwarmStats {
completed: 0,
seeders: 1,
leechers: 0,
downloaded: 0,
complete: 1,
incomplete: 0,
},
interval: tracker.config.announce_interval,
interval_min: tracker.config.min_announce_interval,
Expand Down
8 changes: 4 additions & 4 deletions src/servers/udp/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ pub async fn handle_announce(
let announce_response = AnnounceResponse {
transaction_id: wrapped_announce_request.announce_request.transaction_id,
announce_interval: AnnounceInterval(i64::from(tracker.config.announce_interval) as i32),
leechers: NumberOfPeers(i64::from(response.swarm_stats.leechers) as i32),
seeders: NumberOfPeers(i64::from(response.swarm_stats.seeders) as i32),
leechers: NumberOfPeers(i64::from(response.swarm_stats.incomplete) as i32),
seeders: NumberOfPeers(i64::from(response.swarm_stats.complete) as i32),
peers: response
.peers
.iter()
Expand All @@ -177,8 +177,8 @@ pub async fn handle_announce(
let announce_response = AnnounceResponse {
transaction_id: wrapped_announce_request.announce_request.transaction_id,
announce_interval: AnnounceInterval(i64::from(tracker.config.announce_interval) as i32),
leechers: NumberOfPeers(i64::from(response.swarm_stats.leechers) as i32),
seeders: NumberOfPeers(i64::from(response.swarm_stats.seeders) as i32),
leechers: NumberOfPeers(i64::from(response.swarm_stats.incomplete) as i32),
seeders: NumberOfPeers(i64::from(response.swarm_stats.complete) as i32),
peers: response
.peers
.iter()
Expand Down

0 comments on commit 58a57d3

Please sign in to comment.