mirror of
https://github.com/YGGverse/aquatic.git
synced 2026-04-02 18:55:32 +00:00
udp: add optional peers per torrent statistics
This commit is contained in:
parent
c0ed0eb7db
commit
f0e0a84088
9 changed files with 251 additions and 17 deletions
|
|
@ -7,6 +7,7 @@ use std::time::Instant;
|
|||
|
||||
use aquatic_common::ServerStartInstant;
|
||||
use crossbeam_channel::Receiver;
|
||||
use crossbeam_channel::Sender;
|
||||
use rand::{rngs::SmallRng, SeedableRng};
|
||||
|
||||
use aquatic_common::{CanonicalSocketAddr, PanicSentinel, ValidUntil};
|
||||
|
|
@ -25,6 +26,7 @@ pub fn run_swarm_worker(
|
|||
server_start_instant: ServerStartInstant,
|
||||
request_receiver: Receiver<(SocketWorkerIndex, ConnectedRequest, CanonicalSocketAddr)>,
|
||||
response_sender: ConnectedResponseSender,
|
||||
statistics_sender: Sender<StatisticsMessage>,
|
||||
worker_index: SwarmWorkerIndex,
|
||||
) {
|
||||
let mut torrents = TorrentMaps::default();
|
||||
|
|
@ -86,15 +88,26 @@ pub fn run_swarm_worker(
|
|||
peer_valid_until = ValidUntil::new(server_start_instant, config.cleaning.max_peer_age);
|
||||
|
||||
if now > last_cleaning + cleaning_interval {
|
||||
let (ipv4, ipv6) = torrents.clean_and_get_num_peers(
|
||||
let (ipv4, ipv6) = torrents.clean_and_get_statistics(
|
||||
&config,
|
||||
&state.access_list,
|
||||
server_start_instant,
|
||||
);
|
||||
|
||||
if config.statistics.active() {
|
||||
state.statistics_ipv4.peers[worker_index.0].store(ipv4, Ordering::Release);
|
||||
state.statistics_ipv6.peers[worker_index.0].store(ipv6, Ordering::Release);
|
||||
state.statistics_ipv4.peers[worker_index.0].store(ipv4.0, Ordering::Release);
|
||||
state.statistics_ipv6.peers[worker_index.0].store(ipv6.0, Ordering::Release);
|
||||
|
||||
if let Some(message) = ipv4.1.map(StatisticsMessage::Ipv4PeerHistogram) {
|
||||
if let Err(err) = statistics_sender.try_send(message) {
|
||||
::log::error!("couldn't send statistics message: {:#}", err)
|
||||
}
|
||||
}
|
||||
if let Some(message) = ipv6.1.map(StatisticsMessage::Ipv6PeerHistogram) {
|
||||
if let Err(err) = statistics_sender.try_send(message) {
|
||||
::log::error!("couldn't send statistics message: {:#}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last_cleaning = now;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use aquatic_common::{
|
|||
};
|
||||
|
||||
use aquatic_udp_protocol::*;
|
||||
use hdrhistogram::Histogram;
|
||||
use rand::prelude::SmallRng;
|
||||
|
||||
use crate::common::*;
|
||||
|
|
@ -140,14 +141,28 @@ pub struct TorrentMap<I: Ip>(pub AmortizedIndexMap<InfoHash, TorrentData<I>>);
|
|||
|
||||
impl<I: Ip> TorrentMap<I> {
|
||||
/// Remove forbidden or inactive torrents, reclaim space and return number of remaining peers
|
||||
fn clean_and_get_num_peers(
|
||||
fn clean_and_get_statistics(
|
||||
&mut self,
|
||||
config: &Config,
|
||||
access_list_cache: &mut AccessListCache,
|
||||
access_list_mode: AccessListMode,
|
||||
now: SecondsSinceServerStart,
|
||||
) -> usize {
|
||||
) -> (usize, Option<Histogram<u64>>) {
|
||||
let mut num_peers = 0;
|
||||
|
||||
let mut opt_histogram: Option<Histogram<u64>> = if config.statistics.extended {
|
||||
match Histogram::new(3) {
|
||||
Ok(histogram) => Some(histogram),
|
||||
Err(err) => {
|
||||
::log::error!("Couldn't create peer histogram: {:#}", err);
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
self.0.retain(|info_hash, torrent| {
|
||||
if !access_list_cache
|
||||
.load()
|
||||
|
|
@ -160,12 +175,27 @@ impl<I: Ip> TorrentMap<I> {
|
|||
|
||||
num_peers += torrent.peers.len();
|
||||
|
||||
match opt_histogram {
|
||||
Some(ref mut histogram) if torrent.peers.len() != 0 => {
|
||||
let n = torrent
|
||||
.peers
|
||||
.len()
|
||||
.try_into()
|
||||
.expect("Couldn't fit usize into u64");
|
||||
|
||||
if let Err(err) = histogram.record(n) {
|
||||
::log::error!("Couldn't record {} to histogram: {:#}", n, err);
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
!torrent.peers.is_empty()
|
||||
});
|
||||
|
||||
self.0.shrink_to_fit();
|
||||
|
||||
num_peers
|
||||
(num_peers, opt_histogram)
|
||||
}
|
||||
|
||||
pub fn num_torrents(&self) -> usize {
|
||||
|
|
@ -189,18 +219,25 @@ impl Default for TorrentMaps {
|
|||
|
||||
impl TorrentMaps {
|
||||
/// Remove forbidden or inactive torrents, reclaim space and return number of remaining peers
|
||||
pub fn clean_and_get_num_peers(
|
||||
pub fn clean_and_get_statistics(
|
||||
&mut self,
|
||||
config: &Config,
|
||||
access_list: &Arc<AccessListArcSwap>,
|
||||
server_start_instant: ServerStartInstant,
|
||||
) -> (usize, usize) {
|
||||
) -> (
|
||||
(usize, Option<Histogram<u64>>),
|
||||
(usize, Option<Histogram<u64>>),
|
||||
) {
|
||||
let mut cache = create_access_list_cache(access_list);
|
||||
let mode = config.access_list.mode;
|
||||
let now = server_start_instant.seconds_elapsed();
|
||||
|
||||
let ipv4 = self.ipv4.clean_and_get_num_peers(&mut cache, mode, now);
|
||||
let ipv6 = self.ipv6.clean_and_get_num_peers(&mut cache, mode, now);
|
||||
let ipv4 = self
|
||||
.ipv4
|
||||
.clean_and_get_statistics(config, &mut cache, mode, now);
|
||||
let ipv6 = self
|
||||
.ipv6
|
||||
.clean_and_get_statistics(config, &mut cache, mode, now);
|
||||
|
||||
(ipv4, ipv6)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue