Skip to content

Commit 8accd9f

Browse files
committed
dev: cleanup launcher
1 parent 933eacb commit 8accd9f

19 files changed

+482
-662
lines changed

Cargo.lock

+10-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ use tokio::task::JoinHandle;
2828
use torrust_tracker_configuration::Configuration;
2929

3030
use crate::bootstrap::jobs::{health_check_api, http_tracker, torrent_cleanup, tracker_apis, udp_tracker};
31-
use crate::core;
32-
use crate::servers::http::Version;
31+
use crate::{core, servers};
3332

3433
/// # Panics
3534
///
@@ -68,21 +67,22 @@ pub async fn start(config: Arc<Configuration>, tracker: Arc<core::Tracker>) -> V
6867
udp_tracker_config.bind_address, config.mode
6968
);
7069
} else {
71-
jobs.push(udp_tracker::start_job(udp_tracker_config, tracker.clone()));
70+
jobs.push(udp_tracker::start_job(udp_tracker_config, tracker.clone()).await);
7271
}
7372
}
7473

7574
// Start the HTTP blocks
7675
for http_tracker_config in &config.http_trackers {
77-
if !http_tracker_config.enabled {
78-
continue;
79-
}
80-
jobs.push(http_tracker::start_job(http_tracker_config, tracker.clone(), Version::V1).await);
76+
if let Some(job) = http_tracker::start_job(http_tracker_config, tracker.clone(), servers::http::Version::V1).await {
77+
jobs.push(job);
78+
};
8179
}
8280

8381
// Start HTTP API
8482
if config.http_api.enabled {
85-
jobs.push(tracker_apis::start_job(&config.http_api, tracker.clone()).await);
83+
if let Some(job) = tracker_apis::start_job(&config.http_api, tracker.clone(), servers::apis::Version::V1).await {
84+
jobs.push(job);
85+
};
8686
}
8787

8888
// Start runners to remove torrents without peers, every interval

src/bootstrap/jobs/health_check_api.rs

+5-16
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,16 @@
1515
//!
1616
//! Refer to the [configuration documentation](https://docs.rs/torrust-tracker-configuration)
1717
//! for the API configuration options.
18-
use std::net::SocketAddr;
1918
use std::sync::Arc;
2019

2120
use log::info;
2221
use tokio::sync::oneshot;
2322
use tokio::task::JoinHandle;
2423
use torrust_tracker_configuration::Configuration;
2524

25+
use super::Started;
2626
use crate::servers::health_check_api::server;
2727

28-
/// This is the message that the "launcher" spawned task sends to the main
29-
/// application process to notify the API server was successfully started.
30-
///
31-
/// > **NOTICE**: it does not mean the API server is ready to receive requests.
32-
/// It only means the new server started. It might take some time to the server
33-
/// to be ready to accept request.
34-
#[derive(Debug)]
35-
pub struct ApiServerJobStarted {
36-
pub bound_addr: SocketAddr,
37-
}
38-
3928
/// This function starts a new Health Check API server with the provided
4029
/// configuration.
4130
///
@@ -53,22 +42,22 @@ pub async fn start_job(config: Arc<Configuration>) -> JoinHandle<()> {
5342
.parse::<std::net::SocketAddr>()
5443
.expect("Health Check API bind_address invalid.");
5544

56-
let (tx, rx) = oneshot::channel::<ApiServerJobStarted>();
45+
let (tx_start, rx_start) = oneshot::channel::<Started>();
5746

5847
// Run the API server
5948
let join_handle = tokio::spawn(async move {
6049
info!("Starting Health Check API server: http://{}", bind_addr);
6150

62-
let handle = server::start(bind_addr, tx, config.clone());
51+
let handle = server::start(bind_addr, tx_start, config.clone());
6352

6453
if let Ok(()) = handle.await {
6554
info!("Health Check API server on http://{} stopped", bind_addr);
6655
}
6756
});
6857

6958
// Wait until the API server job is running
70-
match rx.await {
71-
Ok(_msg) => info!("Torrust Health Check API server started"),
59+
match rx_start.await {
60+
Ok(msg) => info!("Torrust Health Check API server started on socket: {}", msg.address),
7261
Err(e) => panic!("the Health Check API server was dropped: {e}"),
7362
}
7463

src/bootstrap/jobs/http_tracker.rs

+38-59
Original file line numberDiff line numberDiff line change
@@ -11,84 +11,63 @@
1111
//!
1212
//! The "**launcher**" is an intermediary thread that decouples the HTTP servers from the process that handles it. The HTTP could be used independently in the future.
1313
//! In that case it would not need to notify a parent process.
14+
use std::net::SocketAddr;
1415
use std::sync::Arc;
1516

1617
use axum_server::tls_rustls::RustlsConfig;
1718
use log::info;
18-
use tokio::sync::oneshot;
1919
use tokio::task::JoinHandle;
2020
use torrust_tracker_configuration::HttpTracker;
2121

2222
use crate::core;
23-
use crate::servers::http::v1::launcher;
23+
use crate::servers::http::server::{HttpServer, HttpServerLauncher};
24+
use crate::servers::http::v1::launcher::Launcher;
2425
use crate::servers::http::Version;
2526

26-
/// This is the message that the "**launcher**" spawned task sends to the main application process to notify that the HTTP server was successfully started.
27-
///
28-
/// > **NOTICE**: it does not mean the HTTP server is ready to receive requests. It only means the new server started. It might take some time to the server to be ready to accept request.
29-
#[derive(Debug)]
30-
pub struct ServerJobStarted();
31-
3227
/// It starts a new HTTP server with the provided configuration and version.
3328
///
3429
/// Right now there is only one version but in the future we could support more than one HTTP tracker version at the same time.
3530
/// This feature allows supporting breaking changes on `BitTorrent` BEPs.
36-
pub async fn start_job(config: &HttpTracker, tracker: Arc<core::Tracker>, version: Version) -> JoinHandle<()> {
37-
match version {
38-
Version::V1 => start_v1(config, tracker.clone()).await,
39-
}
40-
}
41-
31+
///
4232
/// # Panics
4333
///
4434
/// It would panic if the `config::HttpTracker` struct would contain inappropriate values.
45-
async fn start_v1(config: &HttpTracker, tracker: Arc<core::Tracker>) -> JoinHandle<()> {
46-
let bind_addr = config
47-
.bind_address
48-
.parse::<std::net::SocketAddr>()
49-
.expect("Tracker API bind_address invalid.");
50-
let ssl_enabled = config.ssl_enabled;
51-
let ssl_cert_path = config.ssl_cert_path.clone();
52-
let ssl_key_path = config.ssl_key_path.clone();
53-
54-
let (tx, rx) = oneshot::channel::<ServerJobStarted>();
55-
56-
// Run the API server
57-
let join_handle = tokio::spawn(async move {
58-
if !ssl_enabled {
59-
info!("Starting Torrust HTTP tracker server on: http://{}", bind_addr);
60-
61-
let handle = launcher::start(bind_addr, tracker);
62-
63-
tx.send(ServerJobStarted())
64-
.expect("the HTTP tracker server should not be dropped");
65-
66-
if let Ok(()) = handle.await {
67-
info!("Torrust HTTP tracker server on http://{} stopped", bind_addr);
68-
}
69-
} else if ssl_enabled && ssl_cert_path.is_some() && ssl_key_path.is_some() {
70-
info!("Starting Torrust HTTP tracker server on: https://{}", bind_addr);
71-
72-
let ssl_config = RustlsConfig::from_pem_file(ssl_cert_path.unwrap(), ssl_key_path.unwrap())
35+
///
36+
pub async fn start_job(config: &HttpTracker, tracker: Arc<core::Tracker>, version: Version) -> Option<JoinHandle<()>> {
37+
if config.enabled {
38+
let socket = config
39+
.bind_address
40+
.parse::<std::net::SocketAddr>()
41+
.expect("Tracker API bind_address invalid.");
42+
43+
let tls = if let (true, Some(cert), Some(key)) = (&config.ssl_enabled, &config.ssl_cert_path, &config.ssl_key_path) {
44+
let tls = RustlsConfig::from_pem_file(cert, key)
7345
.await
74-
.unwrap();
75-
76-
let handle = launcher::start_tls(bind_addr, ssl_config, tracker);
77-
78-
tx.send(ServerJobStarted())
79-
.expect("the HTTP tracker server should not be dropped");
80-
81-
if let Ok(()) = handle.await {
82-
info!("Torrust HTTP tracker server on https://{} stopped", bind_addr);
83-
}
46+
.expect("Could not read tls cert.");
47+
info!("Using https: cert path: {cert}.");
48+
info!("Using https: key path: {cert}.");
49+
Some(tls)
50+
} else {
51+
info!("Loading HTTP tracker without TLS.");
52+
None
53+
};
54+
55+
match version {
56+
Version::V1 => Some(start_v1(socket, tls, tracker.clone()).await),
8457
}
85-
});
86-
87-
// Wait until the HTTP tracker server job is running
88-
match rx.await {
89-
Ok(_msg) => info!("Torrust HTTP tracker server started"),
90-
Err(e) => panic!("the HTTP tracker server was dropped: {e}"),
58+
} else {
59+
info!("Note: Not loading Http Tracker Service, Not Enabled in Configuration.");
60+
None
9161
}
62+
}
63+
64+
async fn start_v1(socket: SocketAddr, tls: Option<RustlsConfig>, tracker: Arc<core::Tracker>) -> JoinHandle<()> {
65+
let server = HttpServer::new(Launcher::new(socket, tls))
66+
.start(tracker)
67+
.await
68+
.expect("Failed to start Server");
9269

93-
join_handle
70+
tokio::spawn(async move {
71+
server.state.task.await.expect("failed to finish service");
72+
})
9473
}

src/bootstrap/jobs/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,11 @@ pub mod http_tracker;
1111
pub mod torrent_cleanup;
1212
pub mod tracker_apis;
1313
pub mod udp_tracker;
14+
15+
/// This is the message that the "launcher" spawned task sends to the main
16+
/// application process to notify the service was successfully started.
17+
///
18+
#[derive(Debug)]
19+
pub struct Started {
20+
pub address: std::net::SocketAddr,
21+
}

src/bootstrap/jobs/tracker_apis.rs

+36-43
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@
2020
//!
2121
//! Refer to the [configuration documentation](https://docs.rs/torrust-tracker-configuration)
2222
//! for the API configuration options.
23+
use std::net::SocketAddr;
2324
use std::sync::Arc;
2425

2526
use axum_server::tls_rustls::RustlsConfig;
2627
use log::info;
27-
use tokio::sync::oneshot;
2828
use tokio::task::JoinHandle;
2929
use torrust_tracker_configuration::HttpApi;
3030

3131
use crate::core;
32-
use crate::servers::apis::server;
32+
use crate::servers::apis::server::{ApiServer, Launcher};
33+
use crate::servers::apis::Version;
3334

3435
/// This is the message that the "launcher" spawned task sends to the main
3536
/// application process to notify the API server was successfully started.
@@ -49,51 +50,43 @@ pub struct ApiServerJobStarted();
4950
/// # Panics
5051
///
5152
/// It would panic if unable to send the `ApiServerJobStarted` notice.
52-
pub async fn start_job(config: &HttpApi, tracker: Arc<core::Tracker>) -> JoinHandle<()> {
53-
let bind_addr = config
54-
.bind_address
55-
.parse::<std::net::SocketAddr>()
56-
.expect("Tracker API bind_address invalid.");
57-
let ssl_enabled = config.ssl_enabled;
58-
let ssl_cert_path = config.ssl_cert_path.clone();
59-
let ssl_key_path = config.ssl_key_path.clone();
60-
61-
let (tx, rx) = oneshot::channel::<ApiServerJobStarted>();
62-
63-
// Run the API server
64-
let join_handle = tokio::spawn(async move {
65-
if !ssl_enabled {
66-
info!("Starting Torrust APIs server on: http://{}", bind_addr);
67-
68-
let handle = server::start(bind_addr, tracker);
69-
70-
tx.send(ApiServerJobStarted()).expect("the API server should not be dropped");
71-
72-
if let Ok(()) = handle.await {
73-
info!("Torrust APIs server on http://{} stopped", bind_addr);
74-
}
75-
} else if ssl_enabled && ssl_cert_path.is_some() && ssl_key_path.is_some() {
76-
info!("Starting Torrust APIs server on: https://{}", bind_addr);
53+
///
54+
///
55+
pub async fn start_job(config: &HttpApi, tracker: Arc<core::Tracker>, version: Version) -> Option<JoinHandle<()>> {
56+
if config.enabled {
57+
let socket = config
58+
.bind_address
59+
.parse::<std::net::SocketAddr>()
60+
.expect("Tracker API bind_address invalid.");
7761

78-
let ssl_config = RustlsConfig::from_pem_file(ssl_cert_path.unwrap(), ssl_key_path.unwrap())
62+
let tls = if let (true, Some(cert), Some(key)) = (&config.ssl_enabled, &config.ssl_cert_path, &config.ssl_key_path) {
63+
let tls = RustlsConfig::from_pem_file(cert, key)
7964
.await
80-
.unwrap();
81-
82-
let handle = server::start_tls(bind_addr, ssl_config, tracker);
83-
84-
tx.send(ApiServerJobStarted()).expect("the API server should not be dropped");
65+
.expect("Could not read tls cert.");
66+
info!("Using https: cert path: {cert}.");
67+
info!("Using https: key path: {cert}.");
68+
Some(tls)
69+
} else {
70+
info!("Loading HTTP tracker without TLS.");
71+
None
72+
};
8573

86-
if let Ok(()) = handle.await {
87-
info!("Torrust APIs server on https://{} stopped", bind_addr);
88-
}
74+
match version {
75+
Version::V1 => Some(start_v1(socket, tls, tracker.clone()).await),
8976
}
90-
});
91-
92-
// Wait until the APIs server job is running
93-
match rx.await {
94-
Ok(_msg) => info!("Torrust APIs server started"),
95-
Err(e) => panic!("the API server was dropped: {e}"),
77+
} else {
78+
info!("Note: Not loading Http Tracker Service, Not Enabled in Configuration.");
79+
None
9680
}
81+
}
82+
83+
async fn start_v1(socket: SocketAddr, tls: Option<RustlsConfig>, tracker: Arc<core::Tracker>) -> JoinHandle<()> {
84+
let server = ApiServer::new(Launcher::new(socket, tls))
85+
.start(tracker)
86+
.await
87+
.expect("Failed to start Server");
9788

98-
join_handle
89+
tokio::spawn(async move {
90+
server.state.task.await.expect("failed to close service");
91+
})
9992
}

0 commit comments

Comments
 (0)