Skip to content

Commit

Permalink
refactor(api): [#143] remove duplicate code
Browse files Browse the repository at this point in the history
- Extract domain logic: `Tracker::get_torrents_metrics`.
- Move domain logic from web framework controllers to domain services:
  `get_metrics`.
- Remove duplicate code in current Warp API and new Axum API.
  • Loading branch information
josecelano committed Jan 3, 2023
1 parent 7331c82 commit 0615c9f
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 112 deletions.
57 changes: 41 additions & 16 deletions src/api/resource/stats.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,46 @@
use serde::{Deserialize, Serialize};

use crate::tracker::services::statistics::TrackerMetrics;

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct Stats {
pub torrents: u32,
pub seeders: u32,
pub completed: u32,
pub leechers: u32,
pub tcp4_connections_handled: u32,
pub tcp4_announces_handled: u32,
pub tcp4_scrapes_handled: u32,
pub tcp6_connections_handled: u32,
pub tcp6_announces_handled: u32,
pub tcp6_scrapes_handled: u32,
pub udp4_connections_handled: u32,
pub udp4_announces_handled: u32,
pub udp4_scrapes_handled: u32,
pub udp6_connections_handled: u32,
pub udp6_announces_handled: u32,
pub udp6_scrapes_handled: u32,
pub torrents: u64,
pub seeders: u64,
pub completed: u64,
pub leechers: u64,
pub tcp4_connections_handled: u64,
pub tcp4_announces_handled: u64,
pub tcp4_scrapes_handled: u64,
pub tcp6_connections_handled: u64,
pub tcp6_announces_handled: u64,
pub tcp6_scrapes_handled: u64,
pub udp4_connections_handled: u64,
pub udp4_announces_handled: u64,
pub udp4_scrapes_handled: u64,
pub udp6_connections_handled: u64,
pub udp6_announces_handled: u64,
pub udp6_scrapes_handled: u64,
}

impl From<TrackerMetrics> for Stats {
fn from(metrics: TrackerMetrics) -> Self {
Self {
torrents: metrics.torrents_metrics.torrents,
seeders: metrics.torrents_metrics.seeders,
completed: metrics.torrents_metrics.completed,
leechers: metrics.torrents_metrics.leechers,
tcp4_connections_handled: metrics.protocol_metrics.tcp4_connections_handled,
tcp4_announces_handled: metrics.protocol_metrics.tcp4_announces_handled,
tcp4_scrapes_handled: metrics.protocol_metrics.tcp4_scrapes_handled,
tcp6_connections_handled: metrics.protocol_metrics.tcp6_connections_handled,
tcp6_announces_handled: metrics.protocol_metrics.tcp6_announces_handled,
tcp6_scrapes_handled: metrics.protocol_metrics.tcp6_scrapes_handled,
udp4_connections_handled: metrics.protocol_metrics.udp4_connections_handled,
udp4_announces_handled: metrics.protocol_metrics.udp4_announces_handled,
udp4_scrapes_handled: metrics.protocol_metrics.udp4_scrapes_handled,
udp6_connections_handled: metrics.protocol_metrics.udp6_connections_handled,
udp6_announces_handled: metrics.protocol_metrics.udp6_announces_handled,
udp6_scrapes_handled: metrics.protocol_metrics.udp6_scrapes_handled,
}
}
}
50 changes: 2 additions & 48 deletions src/api/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use super::resource::torrent::{ListItem, Torrent};
use super::{ActionStatus, TorrentInfoQuery};
use crate::protocol::info_hash::InfoHash;
use crate::tracker;
use crate::tracker::services::statistics::get_metrics;

fn authenticate(tokens: HashMap<String, String>) -> impl Filter<Extract = (), Error = warp::reject::Rejection> + Clone {
#[derive(Deserialize)]
Expand Down Expand Up @@ -91,54 +92,7 @@ pub fn routes(tracker: &Arc<tracker::Tracker>) -> impl Filter<Extract = impl war
.and(filters::path::end())
.map(move || api_stats.clone())
.and_then(|tracker: Arc<tracker::Tracker>| async move {
let mut results = Stats {
torrents: 0,
seeders: 0,
completed: 0,
leechers: 0,
tcp4_connections_handled: 0,
tcp4_announces_handled: 0,
tcp4_scrapes_handled: 0,
tcp6_connections_handled: 0,
tcp6_announces_handled: 0,
tcp6_scrapes_handled: 0,
udp4_connections_handled: 0,
udp4_announces_handled: 0,
udp4_scrapes_handled: 0,
udp6_connections_handled: 0,
udp6_announces_handled: 0,
udp6_scrapes_handled: 0,
};

let db = tracker.get_torrents().await;

db.values().for_each(|torrent_entry| {
let (seeders, completed, leechers) = torrent_entry.get_stats();
results.seeders += seeders;
results.completed += completed;
results.leechers += leechers;
results.torrents += 1;
});

let stats = tracker.get_stats().await;

#[allow(clippy::cast_possible_truncation)]
{
results.tcp4_connections_handled = stats.tcp4_connections_handled as u32;
results.tcp4_announces_handled = stats.tcp4_announces_handled as u32;
results.tcp4_scrapes_handled = stats.tcp4_scrapes_handled as u32;
results.tcp6_connections_handled = stats.tcp6_connections_handled as u32;
results.tcp6_announces_handled = stats.tcp6_announces_handled as u32;
results.tcp6_scrapes_handled = stats.tcp6_scrapes_handled as u32;
results.udp4_connections_handled = stats.udp4_connections_handled as u32;
results.udp4_announces_handled = stats.udp4_announces_handled as u32;
results.udp4_scrapes_handled = stats.udp4_scrapes_handled as u32;
results.udp6_connections_handled = stats.udp6_connections_handled as u32;
results.udp6_announces_handled = stats.udp6_announces_handled as u32;
results.udp6_scrapes_handled = stats.udp6_scrapes_handled as u32;
}

Result::<_, warp::reject::Rejection>::Ok(reply::json(&results))
Result::<_, warp::reject::Rejection>::Ok(reply::json(&Stats::from(get_metrics(tracker.clone()).await)))
});

// GET /api/torrent/:info_hash
Expand Down
50 changes: 2 additions & 48 deletions src/apis/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use axum::response::Json;
use serde_json::{json, Value};

use crate::api::resource::stats::Stats;
use crate::tracker::services::statistics::get_metrics;
use crate::tracker::Tracker;

#[allow(clippy::unused_async)]
Expand All @@ -14,52 +15,5 @@ pub async fn root() -> Json<Value> {

#[allow(clippy::unused_async)]
pub async fn get_stats(State(tracker): State<Arc<Tracker>>) -> Json<Value> {
let mut results = Stats {
torrents: 0,
seeders: 0,
completed: 0,
leechers: 0,
tcp4_connections_handled: 0,
tcp4_announces_handled: 0,
tcp4_scrapes_handled: 0,
tcp6_connections_handled: 0,
tcp6_announces_handled: 0,
tcp6_scrapes_handled: 0,
udp4_connections_handled: 0,
udp4_announces_handled: 0,
udp4_scrapes_handled: 0,
udp6_connections_handled: 0,
udp6_announces_handled: 0,
udp6_scrapes_handled: 0,
};

let db = tracker.get_torrents().await;

db.values().for_each(|torrent_entry| {
let (seeders, completed, leechers) = torrent_entry.get_stats();
results.seeders += seeders;
results.completed += completed;
results.leechers += leechers;
results.torrents += 1;
});

let stats = tracker.get_stats().await;

#[allow(clippy::cast_possible_truncation)]
{
results.tcp4_connections_handled = stats.tcp4_connections_handled as u32;
results.tcp4_announces_handled = stats.tcp4_announces_handled as u32;
results.tcp4_scrapes_handled = stats.tcp4_scrapes_handled as u32;
results.tcp6_connections_handled = stats.tcp6_connections_handled as u32;
results.tcp6_announces_handled = stats.tcp6_announces_handled as u32;
results.tcp6_scrapes_handled = stats.tcp6_scrapes_handled as u32;
results.udp4_connections_handled = stats.udp4_connections_handled as u32;
results.udp4_announces_handled = stats.udp4_announces_handled as u32;
results.udp4_scrapes_handled = stats.udp4_scrapes_handled as u32;
results.udp6_connections_handled = stats.udp6_connections_handled as u32;
results.udp6_announces_handled = stats.udp6_announces_handled as u32;
results.udp6_scrapes_handled = stats.udp6_scrapes_handled as u32;
}

Json(json!(results))
Json(json!(Stats::from(get_metrics(tracker.clone()).await)))
}
29 changes: 29 additions & 0 deletions src/tracker/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod auth;
pub mod mode;
pub mod peer;
pub mod services;
pub mod statistics;
pub mod torrent;

Expand Down Expand Up @@ -28,6 +29,13 @@ pub struct Tracker {
database: Box<dyn Database>,
}

pub struct TorrentsMetrics {
pub seeders: u64,
pub completed: u64,
pub leechers: u64,
pub torrents: u64,
}

impl Tracker {
/// # Errors
///
Expand Down Expand Up @@ -277,6 +285,27 @@ impl Tracker {
self.torrents.read().await
}

pub async fn get_torrents_metrics(&self) -> TorrentsMetrics {
let mut torrents_metrics = TorrentsMetrics {
seeders: 0,
completed: 0,
leechers: 0,
torrents: 0,
};

let db = self.get_torrents().await;

db.values().for_each(|torrent_entry| {
let (seeders, completed, leechers) = torrent_entry.get_stats();
torrents_metrics.seeders += u64::from(seeders);
torrents_metrics.completed += u64::from(completed);
torrents_metrics.leechers += u64::from(leechers);
torrents_metrics.torrents += 1;
});

torrents_metrics
}

pub async fn get_stats(&self) -> RwLockReadGuard<'_, statistics::Metrics> {
self.stats_repository.get_stats().await
}
Expand Down
1 change: 1 addition & 0 deletions src/tracker/services/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod statistics;
32 changes: 32 additions & 0 deletions src/tracker/services/statistics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::sync::Arc;

use crate::tracker::statistics::Metrics;
use crate::tracker::{TorrentsMetrics, Tracker};

pub struct TrackerMetrics {
pub torrents_metrics: TorrentsMetrics,
pub protocol_metrics: Metrics,
}

pub async fn get_metrics(tracker: Arc<Tracker>) -> TrackerMetrics {
let torrents_metrics = tracker.get_torrents_metrics().await;
let stats = tracker.get_stats().await;

TrackerMetrics {
torrents_metrics,
protocol_metrics: Metrics {
tcp4_connections_handled: stats.tcp4_connections_handled,
tcp4_announces_handled: stats.tcp4_announces_handled,
tcp4_scrapes_handled: stats.tcp4_scrapes_handled,
tcp6_connections_handled: stats.tcp6_connections_handled,
tcp6_announces_handled: stats.tcp6_announces_handled,
tcp6_scrapes_handled: stats.tcp6_scrapes_handled,
udp4_connections_handled: stats.udp4_connections_handled,
udp4_announces_handled: stats.udp4_announces_handled,
udp4_scrapes_handled: stats.udp4_scrapes_handled,
udp6_connections_handled: stats.udp6_connections_handled,
udp6_announces_handled: stats.udp6_announces_handled,
udp6_scrapes_handled: stats.udp6_scrapes_handled,
},
}
}

0 comments on commit 0615c9f

Please sign in to comment.