Skip to content

Commit 3d53b23

Browse files
committed
feat: [torrust#1491] copy torrent repo benchmarking into a new pkg
It will be removed from the `torrent-repository` package, keeping only data strcutures used in production.
1 parent 659d174 commit 3d53b23

34 files changed

+4290
-1
lines changed

.github/workflows/deployment.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,6 @@ jobs:
7878
cargo publish -p torrust-tracker-metrics
7979
cargo publish -p torrust-tracker-primitives
8080
cargo publish -p torrust-tracker-test-helpers
81+
cargo publish -p torrust-tracker-torrent-benchmarking
8182
cargo publish -p torrust-tracker-torrent-repository
8283
cargo publish -p torrust-udp-tracker-server

Cargo.lock

Lines changed: 20 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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ torrust-rest-tracker-api-client = { version = "3.0.0-develop", path = "packages/
6868
torrust-tracker-test-helpers = { version = "3.0.0-develop", path = "packages/test-helpers" }
6969

7070
[workspace]
71-
members = ["console/tracker-client"]
71+
members = ["console/tracker-client", "packages/torrent-repository-benchmarking"]
7272

7373
[profile.dev]
7474
debug = 1
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
[package]
2+
description = "A library to runt benchmarking for different implementations of a repository of torrents files and their peers."
3+
keywords = ["library", "repository", "torrents"]
4+
name = "torrust-tracker-torrent-repository-benchmarking"
5+
readme = "README.md"
6+
7+
authors.workspace = true
8+
categories.workspace = true
9+
documentation.workspace = true
10+
edition.workspace = true
11+
homepage.workspace = true
12+
license.workspace = true
13+
publish.workspace = true
14+
repository.workspace = true
15+
rust-version.workspace = true
16+
version.workspace = true
17+
18+
[dependencies]
19+
aquatic_udp_protocol = "0"
20+
bittorrent-primitives = "0.1.0"
21+
crossbeam-skiplist = "0"
22+
dashmap = "6"
23+
futures = "0"
24+
parking_lot = "0"
25+
tokio = { version = "1", features = ["macros", "net", "rt-multi-thread", "signal", "sync"] }
26+
torrust-tracker-clock = { version = "3.0.0-develop", path = "../clock" }
27+
torrust-tracker-configuration = { version = "3.0.0-develop", path = "../configuration" }
28+
torrust-tracker-primitives = { version = "3.0.0-develop", path = "../primitives" }
29+
zerocopy = "0.7"
30+
31+
[dev-dependencies]
32+
async-std = { version = "1", features = ["attributes", "tokio1"] }
33+
criterion = { version = "0", features = ["async_tokio"] }
34+
rstest = "0"
35+
36+
[[bench]]
37+
harness = false
38+
name = "repository_benchmark"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Torrust Tracker Torrent Repository Benchmarking
2+
3+
A library to runt benchmarking for different implementations of a repository of torrents files and their peers. Torrent repositories are used by the [Torrust Tracker](https://github.com/torrust/torrust-tracker).
4+
5+
## Benchmarking
6+
7+
```console
8+
cargo bench -p torrust-tracker-torrent-repository
9+
```
10+
11+
Example partial output:
12+
13+
```output
14+
Running benches/repository_benchmark.rs (target/release/deps/repository_benchmark-a9b0013c8d09c3c3)
15+
add_one_torrent/RwLockStd
16+
time: [63.057 ns 63.242 ns 63.506 ns]
17+
Found 12 outliers among 100 measurements (12.00%)
18+
2 (2.00%) low severe
19+
2 (2.00%) low mild
20+
2 (2.00%) high mild
21+
6 (6.00%) high severe
22+
add_one_torrent/RwLockStdMutexStd
23+
time: [62.505 ns 63.077 ns 63.817 ns]
24+
```
25+
26+
## Documentation
27+
28+
[Crate documentation](https://docs.rs/torrust-tracker-torrent-repository).
29+
30+
## License
31+
32+
The project is licensed under the terms of the [GNU AFFERO GENERAL PUBLIC LICENSE](./LICENSE).
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
use std::sync::Arc;
2+
use std::time::{Duration, Instant};
3+
4+
use bittorrent_primitives::info_hash::InfoHash;
5+
use futures::stream::FuturesUnordered;
6+
use torrust_tracker_torrent_repository_benchmarking::repository::RepositoryAsync;
7+
8+
use super::utils::{generate_unique_info_hashes, DEFAULT_PEER};
9+
10+
pub async fn add_one_torrent<V, T>(samples: u64) -> Duration
11+
where
12+
V: RepositoryAsync<T> + Default,
13+
{
14+
let start = Instant::now();
15+
16+
for _ in 0..samples {
17+
let torrent_repository = V::default();
18+
19+
let info_hash = InfoHash::default();
20+
21+
torrent_repository.upsert_peer(&info_hash, &DEFAULT_PEER, None).await;
22+
23+
torrent_repository.get_swarm_metadata(&info_hash).await;
24+
}
25+
26+
start.elapsed()
27+
}
28+
29+
// Add one torrent ten thousand times in parallel (depending on the set worker threads)
30+
pub async fn update_one_torrent_in_parallel<V, T>(runtime: &tokio::runtime::Runtime, samples: u64, sleep: Option<u64>) -> Duration
31+
where
32+
V: RepositoryAsync<T> + Default,
33+
Arc<V>: Clone + Send + Sync + 'static,
34+
{
35+
let torrent_repository = Arc::<V>::default();
36+
let info_hash = InfoHash::default();
37+
let handles = FuturesUnordered::new();
38+
39+
// Add the torrent/peer to the torrent repository
40+
torrent_repository.upsert_peer(&info_hash, &DEFAULT_PEER, None).await;
41+
42+
torrent_repository.get_swarm_metadata(&info_hash).await;
43+
44+
let start = Instant::now();
45+
46+
for _ in 0..samples {
47+
let torrent_repository_clone = torrent_repository.clone();
48+
49+
let handle = runtime.spawn(async move {
50+
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER, None).await;
51+
52+
torrent_repository_clone.get_swarm_metadata(&info_hash).await;
53+
54+
if let Some(sleep_time) = sleep {
55+
let start_time = std::time::Instant::now();
56+
57+
while start_time.elapsed().as_nanos() < u128::from(sleep_time) {}
58+
}
59+
});
60+
61+
handles.push(handle);
62+
}
63+
64+
// Await all tasks
65+
futures::future::join_all(handles).await;
66+
67+
start.elapsed()
68+
}
69+
70+
// Add ten thousand torrents in parallel (depending on the set worker threads)
71+
pub async fn add_multiple_torrents_in_parallel<V, T>(
72+
runtime: &tokio::runtime::Runtime,
73+
samples: u64,
74+
sleep: Option<u64>,
75+
) -> Duration
76+
where
77+
V: RepositoryAsync<T> + Default,
78+
Arc<V>: Clone + Send + Sync + 'static,
79+
{
80+
let torrent_repository = Arc::<V>::default();
81+
let info_hashes = generate_unique_info_hashes(samples.try_into().expect("it should fit in a usize"));
82+
let handles = FuturesUnordered::new();
83+
84+
let start = Instant::now();
85+
86+
for info_hash in info_hashes {
87+
let torrent_repository_clone = torrent_repository.clone();
88+
89+
let handle = runtime.spawn(async move {
90+
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER, None).await;
91+
92+
torrent_repository_clone.get_swarm_metadata(&info_hash).await;
93+
94+
if let Some(sleep_time) = sleep {
95+
let start_time = std::time::Instant::now();
96+
97+
while start_time.elapsed().as_nanos() < u128::from(sleep_time) {}
98+
}
99+
});
100+
101+
handles.push(handle);
102+
}
103+
104+
// Await all tasks
105+
futures::future::join_all(handles).await;
106+
107+
start.elapsed()
108+
}
109+
110+
// Async update ten thousand torrents in parallel (depending on the set worker threads)
111+
pub async fn update_multiple_torrents_in_parallel<V, T>(
112+
runtime: &tokio::runtime::Runtime,
113+
samples: u64,
114+
sleep: Option<u64>,
115+
) -> Duration
116+
where
117+
V: RepositoryAsync<T> + Default,
118+
Arc<V>: Clone + Send + Sync + 'static,
119+
{
120+
let torrent_repository = Arc::<V>::default();
121+
let info_hashes = generate_unique_info_hashes(samples.try_into().expect("it should fit in usize"));
122+
let handles = FuturesUnordered::new();
123+
124+
// Add the torrents/peers to the torrent repository
125+
for info_hash in &info_hashes {
126+
torrent_repository.upsert_peer(info_hash, &DEFAULT_PEER, None).await;
127+
torrent_repository.get_swarm_metadata(info_hash).await;
128+
}
129+
130+
let start = Instant::now();
131+
132+
for info_hash in info_hashes {
133+
let torrent_repository_clone = torrent_repository.clone();
134+
135+
let handle = runtime.spawn(async move {
136+
torrent_repository_clone.upsert_peer(&info_hash, &DEFAULT_PEER, None).await;
137+
torrent_repository_clone.get_swarm_metadata(&info_hash).await;
138+
139+
if let Some(sleep_time) = sleep {
140+
let start_time = std::time::Instant::now();
141+
142+
while start_time.elapsed().as_nanos() < u128::from(sleep_time) {}
143+
}
144+
});
145+
146+
handles.push(handle);
147+
}
148+
149+
// Await all tasks
150+
futures::future::join_all(handles).await;
151+
152+
start.elapsed()
153+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod asyn;
2+
pub mod sync;
3+
pub mod utils;

0 commit comments

Comments
 (0)