Skip to content

Commit

Permalink
dev: refactor entry traits
Browse files Browse the repository at this point in the history
  • Loading branch information
da2ce7 committed Mar 22, 2024
1 parent 412adc3 commit 5ac8a30
Show file tree
Hide file tree
Showing 14 changed files with 73 additions and 81 deletions.
65 changes: 24 additions & 41 deletions packages/torrent-repository/src/entry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub mod mutex_std;
pub mod mutex_tokio;
pub mod single;

pub trait ReadInfo {
pub trait Entry {
/// It returns the swarm metadata (statistics) as a struct:
///
/// `(seeders, completed, leechers)`
Expand All @@ -24,27 +24,7 @@ pub trait ReadInfo {

/// Returns the number of Peers
fn get_peers_len(&self) -> usize;
}

/// Same as [`ReadInfo`], but async.
pub trait ReadInfoAsync {
/// It returns the swarm metadata (statistics) as a struct:
///
/// `(seeders, completed, leechers)`
fn get_stats(self) -> impl std::future::Future<Output = SwarmMetadata> + Send;

/// Returns True if Still a Valid Entry according to the Tracker Policy
#[allow(clippy::wrong_self_convention)]
fn is_not_zombie(self, policy: &TrackerPolicy) -> impl std::future::Future<Output = bool> + Send;

/// Returns True if the Peers is Empty
fn peers_is_empty(self) -> impl std::future::Future<Output = bool> + Send;

/// Returns the number of Peers
fn get_peers_len(self) -> impl std::future::Future<Output = usize> + Send;
}

pub trait ReadPeers {
/// Get all swarm peers, optionally limiting the result.
fn get_peers(&self, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;

Expand All @@ -54,20 +34,7 @@ pub trait ReadPeers {
/// It filters out the input peer, typically because we want to return this
/// list of peers to that client peer.
fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
}

/// Same as [`ReadPeers`], but async.
pub trait ReadPeersAsync {
fn get_peers(self, limit: Option<usize>) -> impl std::future::Future<Output = Vec<Arc<peer::Peer>>> + Send;

fn get_peers_for_peer(
self,
client: &peer::Peer,
limit: Option<usize>,
) -> impl std::future::Future<Output = Vec<Arc<peer::Peer>>> + Send;
}

pub trait Update {
/// It updates a peer and returns true if the number of complete downloads have increased.
///
/// The number of peers that have complete downloading is synchronously updated when peers are updated.
Expand All @@ -81,22 +48,38 @@ pub trait Update {
fn remove_inactive_peers(&mut self, current_cutoff: DurationSinceUnixEpoch);
}

/// Same as [`Update`], except not `mut`.
pub trait UpdateSync {
#[allow(clippy::module_name_repetitions)]
pub trait EntrySync {
fn get_stats(&self) -> SwarmMetadata;
fn is_not_zombie(&self, policy: &TrackerPolicy) -> bool;
fn peers_is_empty(&self) -> bool;
fn get_peers_len(&self) -> usize;
fn get_peers(&self, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
fn insert_or_update_peer(&self, peer: &peer::Peer) -> bool;
fn insert_or_update_peer_and_get_stats(&self, peer: &peer::Peer) -> (bool, SwarmMetadata);
fn remove_inactive_peers(&self, current_cutoff: DurationSinceUnixEpoch);
}

/// Same as [`Update`], except not `mut` and async.
pub trait UpdateAsync {
fn insert_or_update_peer(self, peer: &peer::Peer) -> impl std::future::Future<Output = bool> + Send;
#[allow(clippy::module_name_repetitions)]
pub trait EntryAsync {
fn get_stats(self) -> impl std::future::Future<Output = SwarmMetadata> + Send;

#[allow(clippy::wrong_self_convention)]
fn is_not_zombie(self, policy: &TrackerPolicy) -> impl std::future::Future<Output = bool> + Send;
fn peers_is_empty(self) -> impl std::future::Future<Output = bool> + Send;
fn get_peers_len(self) -> impl std::future::Future<Output = usize> + Send;
fn get_peers(self, limit: Option<usize>) -> impl std::future::Future<Output = Vec<Arc<peer::Peer>>> + Send;
fn get_peers_for_peer(
self,
client: &peer::Peer,
limit: Option<usize>,
) -> impl std::future::Future<Output = Vec<Arc<peer::Peer>>> + Send;
fn insert_or_update_peer(self, peer: &peer::Peer) -> impl std::future::Future<Output = bool> + Send;
fn insert_or_update_peer_and_get_stats(
self,
peer: &peer::Peer,
) -> impl std::future::Future<Output = (bool, SwarmMetadata)> + std::marker::Send;

fn remove_inactive_peers(self, current_cutoff: DurationSinceUnixEpoch) -> impl std::future::Future<Output = ()> + Send;
}

Expand All @@ -106,7 +89,7 @@ pub trait UpdateAsync {
/// that's the list of all the peers trying to download the same torrent.
/// The tracker keeps one entry like this for every torrent.
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct Entry {
pub struct Torrent {
/// The swarm: a network of peers that are all trying to download the torrent associated to this entry
#[serde(skip)]
pub(crate) peers: std::collections::BTreeMap<peer::Id, Arc<peer::Peer>>,
Expand Down
8 changes: 2 additions & 6 deletions packages/torrent-repository/src/entry/mutex_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ use torrust_tracker_configuration::TrackerPolicy;
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch};

use super::{ReadInfo, ReadPeers, Update, UpdateSync};
use super::{Entry, EntrySync};
use crate::EntryMutexStd;

impl ReadInfo for EntryMutexStd {
impl EntrySync for EntryMutexStd {
fn get_stats(&self) -> SwarmMetadata {
self.lock().expect("it should get a lock").get_stats()
}
Expand All @@ -23,19 +23,15 @@ impl ReadInfo for EntryMutexStd {
fn get_peers_len(&self) -> usize {
self.lock().expect("it should get a lock").get_peers_len()
}
}

impl ReadPeers for EntryMutexStd {
fn get_peers(&self, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
self.lock().expect("it should get lock").get_peers(limit)
}

fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
self.lock().expect("it should get lock").get_peers_for_peer(client, limit)
}
}

impl UpdateSync for EntryMutexStd {
fn insert_or_update_peer(&self, peer: &peer::Peer) -> bool {
self.lock().expect("it should lock the entry").insert_or_update_peer(peer)
}
Expand Down
9 changes: 2 additions & 7 deletions packages/torrent-repository/src/entry/mutex_tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ use torrust_tracker_configuration::TrackerPolicy;
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch};

use super::{ReadInfo, ReadInfoAsync, ReadPeers, ReadPeersAsync, Update};
use crate::entry::UpdateAsync;
use super::{Entry, EntryAsync};
use crate::EntryMutexTokio;

impl ReadInfoAsync for EntryMutexTokio {
impl EntryAsync for EntryMutexTokio {
async fn get_stats(self) -> SwarmMetadata {
self.lock().await.get_stats()
}
Expand All @@ -24,19 +23,15 @@ impl ReadInfoAsync for EntryMutexTokio {
async fn get_peers_len(self) -> usize {
self.lock().await.get_peers_len()
}
}

impl ReadPeersAsync for EntryMutexTokio {
async fn get_peers(self, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
self.lock().await.get_peers(limit)
}

async fn get_peers_for_peer(self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
self.lock().await.get_peers_for_peer(client, limit)
}
}

impl UpdateAsync for EntryMutexTokio {
async fn insert_or_update_peer(self, peer: &peer::Peer) -> bool {
self.lock().await.insert_or_update_peer(peer)
}
Expand Down
9 changes: 2 additions & 7 deletions packages/torrent-repository/src/entry/single.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ use torrust_tracker_primitives::peer::{self};
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
use torrust_tracker_primitives::DurationSinceUnixEpoch;

use super::{ReadInfo, ReadPeers, Update};
use super::Entry;
use crate::EntrySingle;

impl ReadInfo for EntrySingle {
impl Entry for EntrySingle {
#[allow(clippy::cast_possible_truncation)]
fn get_stats(&self) -> SwarmMetadata {
let complete: u32 = self.peers.values().filter(|peer| peer.is_seeder()).count() as u32;
Expand Down Expand Up @@ -41,9 +41,6 @@ impl ReadInfo for EntrySingle {
fn get_peers_len(&self) -> usize {
self.peers.len()
}
}

impl ReadPeers for EntrySingle {
fn get_peers(&self, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
match limit {
Some(limit) => self.peers.values().take(limit).cloned().collect(),
Expand Down Expand Up @@ -71,9 +68,7 @@ impl ReadPeers for EntrySingle {
.collect(),
}
}
}

impl Update for EntrySingle {
fn insert_or_update_peer(&mut self, peer: &peer::Peer) -> bool {
let mut did_torrent_stats_change: bool = false;

Expand Down
6 changes: 3 additions & 3 deletions packages/torrent-repository/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::sync::Arc;
pub mod entry;
pub mod repository;

pub type EntrySingle = entry::Entry;
pub type EntryMutexStd = Arc<std::sync::Mutex<entry::Entry>>;
pub type EntryMutexTokio = Arc<tokio::sync::Mutex<entry::Entry>>;
pub type EntrySingle = entry::Torrent;
pub type EntryMutexStd = Arc<std::sync::Mutex<entry::Torrent>>;
pub type EntryMutexTokio = Arc<tokio::sync::Mutex<entry::Torrent>>;

pub type TorrentsRwLockStd = repository::RwLockStd<EntrySingle>;
pub type TorrentsRwLockStdMutexStd = repository::RwLockStd<EntryMutexStd>;
Expand Down
8 changes: 6 additions & 2 deletions packages/torrent-repository/src/repository/rw_lock_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};

use super::Repository;
use crate::entry::{ReadInfo, Update};
use crate::entry::Entry;
use crate::{EntrySingle, TorrentsRwLockStd};

impl TorrentsRwLockStd {
Expand All @@ -27,14 +27,18 @@ impl TorrentsRwLockStd {
}
}

impl Repository<EntrySingle> for TorrentsRwLockStd {
impl Repository<EntrySingle> for TorrentsRwLockStd
where
EntrySingle: Entry,
{
fn update_torrent_with_peer_and_get_stats(&self, info_hash: &InfoHash, peer: &peer::Peer) -> (bool, SwarmMetadata) {
let mut db = self.get_torrents_mut();

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

entry.insert_or_update_peer_and_get_stats(peer)
}

fn get(&self, key: &InfoHash) -> Option<EntrySingle> {
let db = self.get_torrents();
db.get(key).cloned()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};

use super::Repository;
use crate::entry::{ReadInfo, UpdateSync};
use crate::entry::{Entry, EntrySync};
use crate::{EntryMutexStd, EntrySingle, TorrentsRwLockStdMutexStd};

impl TorrentsRwLockStdMutexStd {
Expand All @@ -28,7 +28,11 @@ impl TorrentsRwLockStdMutexStd {
}
}

impl Repository<EntryMutexStd> for TorrentsRwLockStdMutexStd {
impl Repository<EntryMutexStd> for TorrentsRwLockStdMutexStd
where
EntryMutexStd: EntrySync,
EntrySingle: Entry,
{
fn update_torrent_with_peer_and_get_stats(&self, info_hash: &InfoHash, peer: &peer::Peer) -> (bool, SwarmMetadata) {
let maybe_entry = self.get_torrents().get(info_hash).cloned();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};

use super::RepositoryAsync;
use crate::entry::{self, ReadInfo, UpdateAsync};
use crate::entry::{Entry, EntryAsync};
use crate::{EntryMutexTokio, EntrySingle, TorrentsRwLockStdMutexTokio};

impl TorrentsRwLockStdMutexTokio {
Expand All @@ -31,7 +31,11 @@ impl TorrentsRwLockStdMutexTokio {
}
}

impl RepositoryAsync<EntryMutexTokio> for TorrentsRwLockStdMutexTokio {
impl RepositoryAsync<EntryMutexTokio> for TorrentsRwLockStdMutexTokio
where
EntryMutexTokio: EntryAsync,
EntrySingle: Entry,
{
async fn update_torrent_with_peer_and_get_stats(&self, info_hash: &InfoHash, peer: &peer::Peer) -> (bool, SwarmMetadata) {
let maybe_entry = self.get_torrents().get(info_hash).cloned();

Expand Down Expand Up @@ -67,7 +71,7 @@ impl RepositoryAsync<EntryMutexTokio> for TorrentsRwLockStdMutexTokio {
async fn get_metrics(&self) -> TorrentsMetrics {
let mut metrics = TorrentsMetrics::default();

let entries: Vec<Arc<tokio::sync::Mutex<entry::Entry>>> = self.get_torrents().values().cloned().collect();
let entries: Vec<_> = self.get_torrents().values().cloned().collect();

for entry in entries {
let stats = entry.lock().await.get_stats();
Expand Down
7 changes: 5 additions & 2 deletions packages/torrent-repository/src/repository/rw_lock_tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};

use super::RepositoryAsync;
use crate::entry::{ReadInfo, Update};
use crate::entry::Entry;
use crate::{EntrySingle, TorrentsRwLockTokio};

impl TorrentsRwLockTokio {
Expand All @@ -29,7 +29,10 @@ impl TorrentsRwLockTokio {
}
}

impl RepositoryAsync<EntrySingle> for TorrentsRwLockTokio {
impl RepositoryAsync<EntrySingle> for TorrentsRwLockTokio
where
EntrySingle: Entry,
{
async fn update_torrent_with_peer_and_get_stats(&self, info_hash: &InfoHash, peer: &peer::Peer) -> (bool, SwarmMetadata) {
let mut db = self.get_torrents_mut().await;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};

use super::RepositoryAsync;
use crate::entry::{ReadInfo, UpdateSync};
use crate::entry::{Entry, EntrySync};
use crate::{EntryMutexStd, EntrySingle, TorrentsRwLockTokioMutexStd};

impl TorrentsRwLockTokioMutexStd {
Expand All @@ -30,7 +30,11 @@ impl TorrentsRwLockTokioMutexStd {
}
}

impl RepositoryAsync<EntryMutexStd> for TorrentsRwLockTokioMutexStd {
impl RepositoryAsync<EntryMutexStd> for TorrentsRwLockTokioMutexStd
where
EntryMutexStd: EntrySync,
EntrySingle: Entry,
{
async fn update_torrent_with_peer_and_get_stats(&self, info_hash: &InfoHash, peer: &peer::Peer) -> (bool, SwarmMetadata) {
let maybe_entry = self.get_torrents().await.get(info_hash).cloned();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};

use super::RepositoryAsync;
use crate::entry::{ReadInfo, ReadInfoAsync, UpdateAsync};
use crate::entry::{Entry, EntryAsync};
use crate::{EntryMutexTokio, EntrySingle, TorrentsRwLockTokioMutexTokio};

impl TorrentsRwLockTokioMutexTokio {
Expand All @@ -30,7 +30,11 @@ impl TorrentsRwLockTokioMutexTokio {
}
}

impl RepositoryAsync<EntryMutexTokio> for TorrentsRwLockTokioMutexTokio {
impl RepositoryAsync<EntryMutexTokio> for TorrentsRwLockTokioMutexTokio
where
EntryMutexTokio: EntryAsync,
EntrySingle: Entry,
{
async fn update_torrent_with_peer_and_get_stats(&self, info_hash: &InfoHash, peer: &peer::Peer) -> (bool, SwarmMetadata) {
let maybe_entry = self.get_torrents().await.get(info_hash).cloned();

Expand Down
4 changes: 2 additions & 2 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ use torrust_tracker_primitives::info_hash::InfoHash;
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
use torrust_tracker_primitives::{peer, TrackerMode};
use torrust_tracker_torrent_repository::entry::{ReadInfo, ReadPeers};
use torrust_tracker_torrent_repository::entry::EntrySync;
use torrust_tracker_torrent_repository::repository::Repository;

use self::auth::Key;
Expand Down Expand Up @@ -1689,7 +1689,7 @@ mod tests {
mod handling_torrent_persistence {

use torrust_tracker_primitives::announce_event::AnnounceEvent;
use torrust_tracker_torrent_repository::entry::ReadInfo;
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};
Expand Down
2 changes: 1 addition & 1 deletion src/core/services/torrent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::sync::Arc;
use torrust_tracker_primitives::info_hash::InfoHash;
use torrust_tracker_primitives::pagination::Pagination;
use torrust_tracker_primitives::peer;
use torrust_tracker_torrent_repository::entry::{ReadInfo, ReadPeers};
use torrust_tracker_torrent_repository::entry::EntrySync;
use torrust_tracker_torrent_repository::repository::Repository;

use crate::core::Tracker;
Expand Down
Loading

0 comments on commit 5ac8a30

Please sign in to comment.