Skip to content

Commit cb9196e

Browse files
committed
Merge #1513: Overhaul stats: Emit events from the torrent-repository package and collect metrics
d154b2a refactor: [#1358] clean Swarm type (Jose Celano) b3b0b71 refactor: [#1358] Swarm, cleaning upsert_peer method (Jose Celano) 47d1eab refactor: [#1358] Swarm tests to use new mock helpers (Jose Celano) b13797e test: [#1358] add tests for events in torrent-repository pkg (Jose Celano) f71211f test: [#1358] add tests to torrust_tracker_torrent_repository::swarms::Swarms (Jose Celano) 3d7e6ff test: [#1358] add tests to torrust_tracker_torrent_repository::swarm::Swarm (Jose Celano) 0e38707 fix: [#1358] revert Hash impl for Swarm (Jose Celano) c9a893c refactor: [#1358] rename metrics for clarity (Jose Celano) 8ee258e refactor: [#1358] use the new field info-hash as ID for the Swarm (Hash,PartialEq) (Jose Celano) dfba00c feat: [#1358] allow disabling the event sender in the torrent-repository pkg (Jose Celano) 60c00e8 feat: [#1358] add info-hash to all torrent-repository events (Jose Celano) c706a1b refactor: [#1358] move logs (Jose Celano) daba8a0 feat: [#1358] new metric in torrent-repository: total number of downloads (Jose Celano) 01a9970 feat: [#1358] new metric in torrent-repository: total number of peers (Jose Celano) 269d273 refactor: [#1358] rename metric (Jose Celano) ba2033b fix: [#1358] trigger PeerRemoved event when peer is removed due to inactivity (Jose Celano) d47483f feat: [#1358] new metric in torrent-repository: total number of torrents (Jose Celano) 29a2dfd dev: change default config (Jose Celano) 1eb545c feat: [#1358] remove persistent metric from torrent-repository pkg (Jose Celano) 6d95d1a refactor: [#1358] inject event sender in Swarm type (Jose Celano) 2c479a1 refactor: [#1358] inject event sender in Swarms type (Jose Celano) 68b930d feat: [#1495] expose new torrent-repositoru metrics via the REST API (Jose Celano) 41f4022 feat: [#1358] inject Swarms into InMemoryTorrentRepository in testing code (Jose Celano) 95766bb feat: [#1358] inject Swarms into InMemoryTorrentRepository in production code (Jose Celano) f986bda feat: [#1358] add the and run the event listener when the tracker starts (Jose Celano) 2522ad4 feat: [#1358] basic scaffolding for events in torrent-repository pkg (Jose Celano) Pull request description: Emit events from the `torrent-repository package` and collect metrics. In this PR, I'm only planning to include four metrics. The ones we have in the current `stats` endpoint: ```json { "torrents": 387044, "seeders": 183887, "completed": 1260584, "leechers": 249136, } ``` However, I will rename them to: ``` { "torrent_repository_per_session_all_instances_all_torrents_total": 387044, "torrent_repository_per_session_all_instances_all_seeders_total": 183887, "torrent_repository_per_session_all_instances_all_torrents_downloads_total": 1260584, "torrent_repository_per_session_all_instances_all_leechers_total": 249136, } ``` **UPDATE:** I will not use those long names but "labels". It's only to explain what they represent. - per session: since the main tracker process started. - all instances: all tracker servers (UDP or HTTP) running on different ports. - all torrents: all swarms. Becuase the current names are too ambiguous. See #1502 (comment). ### How to test 1. Run the tracker. 2. Use the tracker client to make an announce request. ``` cargo run -p torrust-tracker-client --bin udp_tracker_client announce udp://127.0.0.1:6969 443c7602b4fde83d1154d6d9da48808418b181b6 | jq ``` 3. Use the REST API to get the metric value. ``` curl -s "http://localhost:1212/api/v1/metrics?token=MyAccessToken&format=prometheus" | grep torrent_repository_peers_total ``` ### Subtasks - [x] Add basic event scaffolding in the `torrent-respository` package. - [x] Run the event listener for the torrent-repository package when the tracker starts. - [x] Add the `TorrentRepositoryContainer` and run the listener when the tracker starts. - [x] In production code: use the `Swarms` service provided by the `TorrentRepositoryContainer` in the `TrackerCoreContainer` (otherwise they will be unrelated). - [x] In testing code: use the `Swarms` service provided by the `TorrentRepositoryContainer` in the `TrackerCoreContainer` (otherwise they will be unrelated). - [x] Expose the new metrics via the `metrics` API endpoint (even if it will have no value yet). - [x] Inject the event sender in `Swarms` and `Swarm` type to be able to send events from them. - [x] In `Swarms` type. - [x] In `Swarm` type. - [x] #1516 - [x] Star triggering events and process them to update the metrics in the metrics collection. One event and the corresponding affected metrics at the time. - [x] `TorrentAdded` -> Increase torrents counter (all instances, all torrents) - [x] `Torrentremoved` -> Decrease torrents counter (all instances, all torrents) - [x] `PeerAdded` -> Increase peers counter (total, seeders, leechers) - [x] `PeerRemoved` -> Decrease peers counter (total, seeders, leechers) - [x] `PeerUdpated` -> Decrease peers counter (total, seeders, leechers) - [x] `PeerDownloadCompleted` -> Increase torrent downloads counter (all instances, all torrents) - [x] Add tests to check that events have been sent. - [x] Add tests to check that metrics are updated after receiving the event. ACKs for top commit: josecelano: ACK d154b2a Tree-SHA512: d4946847dae38b51bc6027b4de25d7e2ad5b1042294913008f503c590c81e586ed083ab980613d647a0f867601f7bd482f4c004628c01cdfffc9d8b810bb670e
2 parents 93fdf31 + d154b2a commit cb9196e

File tree

68 files changed

+2576
-709
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+2576
-709
lines changed

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ torrust-rest-tracker-api-core = { version = "3.0.0-develop", path = "packages/re
5555
torrust-server-lib = { version = "3.0.0-develop", path = "packages/server-lib" }
5656
torrust-tracker-clock = { version = "3.0.0-develop", path = "packages/clock" }
5757
torrust-tracker-configuration = { version = "3.0.0-develop", path = "packages/configuration" }
58+
torrust-tracker-torrent-repository = { version = "3.0.0-develop", path = "packages/torrent-repository" }
5859
torrust-udp-tracker-server = { version = "3.0.0-develop", path = "packages/udp-tracker-server" }
5960
tracing = "0"
6061
tracing-subscriber = { version = "0", features = ["json"] }

packages/axum-http-tracker-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ torrust-server-lib = { version = "3.0.0-develop", path = "../server-lib" }
3333
torrust-tracker-clock = { version = "3.0.0-develop", path = "../clock" }
3434
torrust-tracker-configuration = { version = "3.0.0-develop", path = "../configuration" }
3535
torrust-tracker-primitives = { version = "3.0.0-develop", path = "../primitives" }
36+
torrust-tracker-torrent-repository = { version = "3.0.0-develop", path = "../torrent-repository" }
3637
tower = { version = "0", features = ["timeout"] }
3738
tower-http = { version = "0", features = ["compression-full", "cors", "propagate-header", "request-id", "trace"] }
3839
tracing = "0"

packages/axum-http-tracker-server/src/environment.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use torrust_axum_server::tsl::make_rust_tls;
1010
use torrust_server_lib::registar::Registar;
1111
use torrust_tracker_configuration::{logging, Configuration};
1212
use torrust_tracker_primitives::peer;
13+
use torrust_tracker_torrent_repository::container::TorrentRepositoryContainer;
1314

1415
use crate::server::{HttpServer, Launcher, Running, Stopped};
1516

@@ -24,12 +25,12 @@ pub struct Environment<S> {
2425

2526
impl<S> Environment<S> {
2627
/// Add a torrent to the tracker
27-
pub fn add_torrent_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) {
28-
let _number_of_downloads_increased = self
29-
.container
28+
pub async fn add_torrent_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
29+
self.container
3030
.tracker_core_container
3131
.in_memory_torrent_repository
32-
.upsert_peer(info_hash, peer, None);
32+
.upsert_peer(info_hash, peer, None)
33+
.await
3334
}
3435
}
3536

@@ -143,7 +144,15 @@ impl EnvContainer {
143144
.expect("missing HTTP tracker configuration");
144145
let http_tracker_config = Arc::new(http_tracker_config[0].clone());
145146

146-
let tracker_core_container = Arc::new(TrackerCoreContainer::initialize(&core_config));
147+
let torrent_repository_container = Arc::new(TorrentRepositoryContainer::initialize(
148+
configuration.core.tracker_usage_statistics.into(),
149+
));
150+
151+
let tracker_core_container = Arc::new(TrackerCoreContainer::initialize_from(
152+
&core_config,
153+
&torrent_repository_container,
154+
));
155+
147156
let http_tracker_container =
148157
HttpTrackerCoreContainer::initialize_from_tracker_core(&tracker_core_container, &http_tracker_config);
149158

packages/axum-http-tracker-server/src/server.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ mod tests {
260260
use torrust_server_lib::registar::Registar;
261261
use torrust_tracker_configuration::{logging, Configuration};
262262
use torrust_tracker_test_helpers::configuration::ephemeral_public;
263+
use torrust_tracker_torrent_repository::container::TorrentRepositoryContainer;
263264

264265
use crate::server::{HttpServer, Launcher};
265266

@@ -279,7 +280,7 @@ mod tests {
279280
let http_core_broadcaster = Broadcaster::default();
280281
let http_stats_repository = Arc::new(Repository::new());
281282
let http_stats_event_bus = Arc::new(EventBus::new(
282-
configuration.core.tracker_usage_statistics,
283+
configuration.core.tracker_usage_statistics.into(),
283284
http_core_broadcaster.clone(),
284285
));
285286

@@ -289,7 +290,14 @@ mod tests {
289290
let _unused = run_event_listener(http_stats_event_bus.receiver(), &http_stats_repository);
290291
}
291292

292-
let tracker_core_container = Arc::new(TrackerCoreContainer::initialize(&core_config));
293+
let torrent_repository_container = Arc::new(TorrentRepositoryContainer::initialize(
294+
configuration.core.tracker_usage_statistics.into(),
295+
));
296+
297+
let tracker_core_container = Arc::new(TrackerCoreContainer::initialize_from(
298+
&core_config,
299+
&torrent_repository_container,
300+
));
293301

294302
let announce_service = Arc::new(AnnounceService::new(
295303
tracker_core_container.core_config.clone(),

packages/axum-http-tracker-server/src/v1/handlers/announce.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ mod tests {
168168
let http_core_broadcaster = Broadcaster::default();
169169
let http_stats_repository = Arc::new(Repository::new());
170170
let http_stats_event_bus = Arc::new(EventBus::new(
171-
config.core.tracker_usage_statistics,
171+
config.core.tracker_usage_statistics.into(),
172172
http_core_broadcaster.clone(),
173173
));
174174

packages/axum-http-tracker-server/src/v1/handlers/scrape.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ mod tests {
139139
let http_core_broadcaster = Broadcaster::default();
140140
let http_stats_repository = Arc::new(Repository::new());
141141
let http_stats_event_bus = Arc::new(EventBus::new(
142-
config.core.tracker_usage_statistics,
142+
config.core.tracker_usage_statistics.into(),
143143
http_core_broadcaster.clone(),
144144
));
145145

packages/axum-http-tracker-server/tests/server/v1/contract.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ mod for_all_config_modes {
474474
let previously_announced_peer = PeerBuilder::default().with_peer_id(&PeerId(*b"-qB00000000000000001")).build();
475475

476476
// Add the Peer 1
477-
env.add_torrent_peer(&info_hash, &previously_announced_peer);
477+
env.add_torrent_peer(&info_hash, &previously_announced_peer).await;
478478

479479
// Announce the new Peer 2. This new peer is non included on the response peer list
480480
let response = Client::new(*env.bind_address())
@@ -517,7 +517,7 @@ mod for_all_config_modes {
517517
.with_peer_id(&PeerId(*b"-qB00000000000000001"))
518518
.with_peer_addr(&SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0x69, 0x69, 0x69, 0x69)), 8080))
519519
.build();
520-
env.add_torrent_peer(&info_hash, &peer_using_ipv4);
520+
env.add_torrent_peer(&info_hash, &peer_using_ipv4).await;
521521

522522
// Announce a peer using IPV6
523523
let peer_using_ipv6 = PeerBuilder::default()
@@ -527,7 +527,7 @@ mod for_all_config_modes {
527527
8080,
528528
))
529529
.build();
530-
env.add_torrent_peer(&info_hash, &peer_using_ipv6);
530+
env.add_torrent_peer(&info_hash, &peer_using_ipv6).await;
531531

532532
// Announce the new Peer.
533533
let response = Client::new(*env.bind_address())
@@ -625,7 +625,7 @@ mod for_all_config_modes {
625625
let previously_announced_peer = PeerBuilder::default().with_peer_id(&PeerId(*b"-qB00000000000000001")).build();
626626

627627
// Add the Peer 1
628-
env.add_torrent_peer(&info_hash, &previously_announced_peer);
628+
env.add_torrent_peer(&info_hash, &previously_announced_peer).await;
629629

630630
// Announce the new Peer 2 accepting compact responses
631631
let response = Client::new(*env.bind_address())
@@ -666,7 +666,7 @@ mod for_all_config_modes {
666666
let previously_announced_peer = PeerBuilder::default().with_peer_id(&PeerId(*b"-qB00000000000000001")).build();
667667

668668
// Add the Peer 1
669-
env.add_torrent_peer(&info_hash, &previously_announced_peer);
669+
env.add_torrent_peer(&info_hash, &previously_announced_peer).await;
670670

671671
// Announce the new Peer 2 without passing the "compact" param
672672
// By default it should respond with the compact peer list
@@ -787,7 +787,8 @@ mod for_all_config_modes {
787787
.container
788788
.tracker_core_container
789789
.in_memory_torrent_repository
790-
.get_torrent_peers(&info_hash);
790+
.get_torrent_peers(&info_hash)
791+
.await;
791792
let peer_addr = peers[0].peer_addr;
792793

793794
assert_eq!(peer_addr.ip(), client_ip);
@@ -829,7 +830,8 @@ mod for_all_config_modes {
829830
.container
830831
.tracker_core_container
831832
.in_memory_torrent_repository
832-
.get_torrent_peers(&info_hash);
833+
.get_torrent_peers(&info_hash)
834+
.await;
833835
let peer_addr = peers[0].peer_addr;
834836

835837
assert_eq!(
@@ -878,7 +880,8 @@ mod for_all_config_modes {
878880
.container
879881
.tracker_core_container
880882
.in_memory_torrent_repository
881-
.get_torrent_peers(&info_hash);
883+
.get_torrent_peers(&info_hash)
884+
.await;
882885
let peer_addr = peers[0].peer_addr;
883886

884887
assert_eq!(
@@ -925,7 +928,8 @@ mod for_all_config_modes {
925928
.container
926929
.tracker_core_container
927930
.in_memory_torrent_repository
928-
.get_torrent_peers(&info_hash);
931+
.get_torrent_peers(&info_hash)
932+
.await;
929933
let peer_addr = peers[0].peer_addr;
930934

931935
assert_eq!(peer_addr.ip(), IpAddr::from_str("150.172.238.178").unwrap());
@@ -1010,7 +1014,8 @@ mod for_all_config_modes {
10101014
.with_peer_id(&PeerId(*b"-qB00000000000000001"))
10111015
.with_bytes_pending_to_download(1)
10121016
.build(),
1013-
);
1017+
)
1018+
.await;
10141019

10151020
let response = Client::new(*env.bind_address())
10161021
.scrape(
@@ -1050,7 +1055,8 @@ mod for_all_config_modes {
10501055
.with_peer_id(&PeerId(*b"-qB00000000000000001"))
10511056
.with_no_bytes_pending_to_download()
10521057
.build(),
1053-
);
1058+
)
1059+
.await;
10541060

10551061
let response = Client::new(*env.bind_address())
10561062
.scrape(
@@ -1282,7 +1288,8 @@ mod configured_as_whitelisted {
12821288
.with_peer_id(&PeerId(*b"-qB00000000000000001"))
12831289
.with_bytes_pending_to_download(1)
12841290
.build(),
1285-
);
1291+
)
1292+
.await;
12861293

12871294
let response = Client::new(*env.bind_address())
12881295
.scrape(
@@ -1318,7 +1325,8 @@ mod configured_as_whitelisted {
13181325
.with_peer_id(&PeerId(*b"-qB00000000000000001"))
13191326
.with_bytes_pending_to_download(1)
13201327
.build(),
1321-
);
1328+
)
1329+
.await;
13221330

13231331
env.container
13241332
.tracker_core_container
@@ -1494,7 +1502,8 @@ mod configured_as_private {
14941502
.with_peer_id(&PeerId(*b"-qB00000000000000001"))
14951503
.with_bytes_pending_to_download(1)
14961504
.build(),
1497-
);
1505+
)
1506+
.await;
14981507

14991508
let response = Client::new(*env.bind_address())
15001509
.scrape(
@@ -1525,7 +1534,8 @@ mod configured_as_private {
15251534
.with_peer_id(&PeerId(*b"-qB00000000000000001"))
15261535
.with_bytes_pending_to_download(1)
15271536
.build(),
1528-
);
1537+
)
1538+
.await;
15291539

15301540
let expiring_key = env
15311541
.container
@@ -1576,7 +1586,8 @@ mod configured_as_private {
15761586
.with_peer_id(&PeerId(*b"-qB00000000000000001"))
15771587
.with_bytes_pending_to_download(1)
15781588
.build(),
1579-
);
1589+
)
1590+
.await;
15801591

15811592
let false_key: Key = "YZSl4lMZupRuOpSRC3krIKR5BPB14nrJ".parse().unwrap();
15821593

packages/axum-rest-tracker-api-server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ torrust-tracker-clock = { version = "3.0.0-develop", path = "../clock" }
3939
torrust-tracker-configuration = { version = "3.0.0-develop", path = "../configuration" }
4040
torrust-tracker-metrics = { version = "3.0.0-develop", path = "../metrics" }
4141
torrust-tracker-primitives = { version = "3.0.0-develop", path = "../primitives" }
42+
torrust-tracker-torrent-repository = { version = "3.0.0-develop", path = "../torrent-repository" }
4243
torrust-udp-tracker-server = { version = "3.0.0-develop", path = "../udp-tracker-server" }
4344
tower = { version = "0", features = ["timeout"] }
4445
tower-http = { version = "0", features = ["compression-full", "cors", "propagate-header", "request-id", "trace"] }

packages/axum-rest-tracker-api-server/src/environment.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use torrust_rest_tracker_api_core::container::TrackerHttpApiCoreContainer;
1212
use torrust_server_lib::registar::Registar;
1313
use torrust_tracker_configuration::{logging, Configuration};
1414
use torrust_tracker_primitives::peer;
15+
use torrust_tracker_torrent_repository::container::TorrentRepositoryContainer;
1516
use torrust_udp_tracker_server::container::UdpTrackerServerContainer;
1617

1718
use crate::server::{ApiServer, Launcher, Running, Stopped};
@@ -32,12 +33,12 @@ where
3233
S: std::fmt::Debug + std::fmt::Display,
3334
{
3435
/// Add a torrent to the tracker
35-
pub fn add_torrent_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) {
36-
let _number_of_downloads_increased = self
37-
.container
36+
pub async fn add_torrent_peer(&self, info_hash: &InfoHash, peer: &peer::Peer) -> bool {
37+
self.container
3838
.tracker_core_container
3939
.in_memory_torrent_repository
40-
.upsert_peer(info_hash, peer, None);
40+
.upsert_peer(info_hash, peer, None)
41+
.await
4142
}
4243
}
4344

@@ -172,14 +173,25 @@ impl EnvContainer {
172173
.clone(),
173174
);
174175

175-
let tracker_core_container = Arc::new(TrackerCoreContainer::initialize(&core_config));
176+
let torrent_repository_container = Arc::new(TorrentRepositoryContainer::initialize(
177+
core_config.tracker_usage_statistics.into(),
178+
));
179+
180+
let tracker_core_container = Arc::new(TrackerCoreContainer::initialize_from(
181+
&core_config,
182+
&torrent_repository_container,
183+
));
184+
176185
let http_tracker_core_container =
177186
HttpTrackerCoreContainer::initialize_from_tracker_core(&tracker_core_container, &http_tracker_config);
187+
178188
let udp_tracker_core_container =
179189
UdpTrackerCoreContainer::initialize_from_tracker_core(&tracker_core_container, &udp_tracker_config);
190+
180191
let udp_tracker_server_container = UdpTrackerServerContainer::initialize(&core_config);
181192

182193
let tracker_http_api_core_container = TrackerHttpApiCoreContainer::initialize_from(
194+
&torrent_repository_container,
183195
&tracker_core_container,
184196
&http_tracker_core_container,
185197
&udp_tracker_core_container,

0 commit comments

Comments
 (0)