Skip to content

Commit a8f3a97

Browse files
committed
refactor: [#1551] extract event handler for each udp event
1 parent 89ac87c commit a8f3a97

File tree

8 files changed

+820
-739
lines changed

8 files changed

+820
-739
lines changed

packages/udp-tracker-server/src/statistics/event/handler.rs

Lines changed: 0 additions & 739 deletions
This file was deleted.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use std::sync::Arc;
2+
3+
use bittorrent_udp_tracker_core::services::banning::BanService;
4+
use tokio::sync::RwLock;
5+
use torrust_tracker_metrics::label::LabelSet;
6+
use torrust_tracker_metrics::{label_name, metric_name};
7+
use torrust_tracker_primitives::DurationSinceUnixEpoch;
8+
9+
use crate::event::{ConnectionContext, ErrorKind, UdpRequestKind};
10+
use crate::statistics::repository::Repository;
11+
use crate::statistics::UDP_TRACKER_SERVER_ERRORS_TOTAL;
12+
13+
pub async fn handle_event(
14+
context: ConnectionContext,
15+
kind: Option<UdpRequestKind>,
16+
error: ErrorKind,
17+
stats_repository: &Repository,
18+
ban_service: &Arc<RwLock<BanService>>,
19+
now: DurationSinceUnixEpoch,
20+
) {
21+
// Increase the number of errors
22+
// code-review: should we ban IP due to other errors too?
23+
if let ErrorKind::ConnectionCookie(_msg) = error {
24+
let mut ban_service = ban_service.write().await;
25+
ban_service.increase_counter(&context.client_socket_addr().ip());
26+
}
27+
28+
// Global fixed metrics
29+
match context.client_socket_addr().ip() {
30+
std::net::IpAddr::V4(_) => {
31+
stats_repository.increase_udp4_errors().await;
32+
}
33+
std::net::IpAddr::V6(_) => {
34+
stats_repository.increase_udp6_errors().await;
35+
}
36+
}
37+
38+
// Extendable metrics
39+
let mut label_set = LabelSet::from(context);
40+
if let Some(kind) = kind {
41+
label_set.upsert(label_name!("request_kind"), kind.to_string().into());
42+
}
43+
match stats_repository
44+
.increase_counter(&metric_name!(UDP_TRACKER_SERVER_ERRORS_TOTAL), &label_set, now)
45+
.await
46+
{
47+
Ok(()) => {}
48+
Err(err) => tracing::error!("Failed to increase the counter: {}", err),
49+
};
50+
}
51+
52+
#[cfg(test)]
53+
mod tests {
54+
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
55+
use std::sync::Arc;
56+
57+
use bittorrent_udp_tracker_core::services::banning::BanService;
58+
use torrust_tracker_clock::clock::Time;
59+
use torrust_tracker_primitives::service_binding::{Protocol, ServiceBinding};
60+
61+
use crate::event::{ConnectionContext, Event};
62+
use crate::statistics::event::handler::error::ErrorKind;
63+
use crate::statistics::event::handler::handle_event;
64+
use crate::statistics::repository::Repository;
65+
use crate::CurrentClock;
66+
67+
#[tokio::test]
68+
async fn should_increase_the_udp4_errors_counter_when_it_receives_a_udp4_error_event() {
69+
let stats_repository = Repository::new();
70+
let ban_service = Arc::new(tokio::sync::RwLock::new(BanService::new(1)));
71+
72+
handle_event(
73+
Event::UdpError {
74+
context: ConnectionContext::new(
75+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080),
76+
ServiceBinding::new(
77+
Protocol::UDP,
78+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969),
79+
)
80+
.unwrap(),
81+
),
82+
kind: None,
83+
error: ErrorKind::RequestParse("Invalid request format".to_string()),
84+
},
85+
&stats_repository,
86+
&ban_service,
87+
CurrentClock::now(),
88+
)
89+
.await;
90+
91+
let stats = stats_repository.get_stats().await;
92+
93+
assert_eq!(stats.udp4_errors_handled, 1);
94+
}
95+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
mod error;
2+
mod request_aborted;
3+
mod request_accepted;
4+
mod request_banned;
5+
mod request_received;
6+
mod response_sent;
7+
8+
use std::sync::Arc;
9+
10+
use bittorrent_udp_tracker_core::services::banning::BanService;
11+
use tokio::sync::RwLock;
12+
use torrust_tracker_primitives::DurationSinceUnixEpoch;
13+
14+
use crate::event::Event;
15+
use crate::statistics::repository::Repository;
16+
17+
pub async fn handle_event(
18+
event: Event,
19+
stats_repository: &Repository,
20+
ban_service: &Arc<RwLock<BanService>>,
21+
now: DurationSinceUnixEpoch,
22+
) {
23+
match event {
24+
Event::UdpRequestAborted { context } => {
25+
request_aborted::handle_event(context, stats_repository, now).await;
26+
}
27+
Event::UdpRequestBanned { context } => {
28+
request_banned::handle_event(context, stats_repository, now).await;
29+
}
30+
Event::UdpRequestReceived { context } => {
31+
request_received::handle_event(context, stats_repository, now).await;
32+
}
33+
Event::UdpRequestAccepted { context, kind } => {
34+
request_accepted::handle_event(context, kind, stats_repository, now).await;
35+
}
36+
Event::UdpResponseSent {
37+
context,
38+
kind,
39+
req_processing_time,
40+
} => {
41+
response_sent::handle_event(context, kind, req_processing_time, stats_repository, now).await;
42+
}
43+
Event::UdpError { context, kind, error } => {
44+
error::handle_event(context, kind, error, stats_repository, ban_service, now).await;
45+
}
46+
}
47+
48+
tracing::debug!("stats: {:?}", stats_repository.get_stats().await);
49+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
use torrust_tracker_metrics::label::LabelSet;
2+
use torrust_tracker_metrics::metric_name;
3+
use torrust_tracker_primitives::DurationSinceUnixEpoch;
4+
5+
use crate::event::ConnectionContext;
6+
use crate::statistics::repository::Repository;
7+
use crate::statistics::UDP_TRACKER_SERVER_REQUESTS_ABORTED_TOTAL;
8+
9+
pub async fn handle_event(context: ConnectionContext, stats_repository: &Repository, now: DurationSinceUnixEpoch) {
10+
// Global fixed metrics
11+
stats_repository.increase_udp_requests_aborted().await;
12+
13+
// Extendable metrics
14+
match stats_repository
15+
.increase_counter(
16+
&metric_name!(UDP_TRACKER_SERVER_REQUESTS_ABORTED_TOTAL),
17+
&LabelSet::from(context),
18+
now,
19+
)
20+
.await
21+
{
22+
Ok(()) => {}
23+
Err(err) => tracing::error!("Failed to increase the counter: {}", err),
24+
};
25+
}
26+
27+
#[cfg(test)]
28+
mod tests {
29+
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
30+
use std::sync::Arc;
31+
32+
use bittorrent_udp_tracker_core::services::banning::BanService;
33+
use torrust_tracker_clock::clock::Time;
34+
use torrust_tracker_primitives::service_binding::{Protocol, ServiceBinding};
35+
36+
use crate::event::{ConnectionContext, Event};
37+
use crate::statistics::event::handler::handle_event;
38+
use crate::statistics::repository::Repository;
39+
use crate::CurrentClock;
40+
41+
#[tokio::test]
42+
async fn should_increase_the_number_of_aborted_requests_when_it_receives_a_udp_request_aborted_event() {
43+
let stats_repository = Repository::new();
44+
let ban_service = Arc::new(tokio::sync::RwLock::new(BanService::new(1)));
45+
46+
handle_event(
47+
Event::UdpRequestAborted {
48+
context: ConnectionContext::new(
49+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080),
50+
ServiceBinding::new(
51+
Protocol::UDP,
52+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969),
53+
)
54+
.unwrap(),
55+
),
56+
},
57+
&stats_repository,
58+
&ban_service,
59+
CurrentClock::now(),
60+
)
61+
.await;
62+
63+
let stats = stats_repository.get_stats().await;
64+
65+
assert_eq!(stats.udp_requests_aborted, 1);
66+
}
67+
68+
#[tokio::test]
69+
async fn should_increase_the_udp_abort_counter_when_it_receives_a_udp_abort_event() {
70+
let stats_repository = Repository::new();
71+
let ban_service = Arc::new(tokio::sync::RwLock::new(BanService::new(1)));
72+
73+
handle_event(
74+
Event::UdpRequestAborted {
75+
context: ConnectionContext::new(
76+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080),
77+
ServiceBinding::new(
78+
Protocol::UDP,
79+
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969),
80+
)
81+
.unwrap(),
82+
),
83+
},
84+
&stats_repository,
85+
&ban_service,
86+
CurrentClock::now(),
87+
)
88+
.await;
89+
let stats = stats_repository.get_stats().await;
90+
assert_eq!(stats.udp_requests_aborted, 1);
91+
}
92+
}

0 commit comments

Comments
 (0)