torrust-tracker
torrust-tracker copied to clipboard
Tracker Checker: handle HTTP Tracker timeouts
Parent issue: https://github.com/torrust/torrust-tracker/issues/677 Relates to: https://github.com/torrust/torrust-tracker/issues/679
NOTE: Although this issue could be implemented independently I think it would be better if it's implemented after implementing https://github.com/torrust/torrust-tracker/issues/679.
You can run a Tracker Checker with:
TORRUST_CHECKER_CONFIG='{
"udp_trackers": [],
"http_trackers": ["http://127.0.0.1:7070"],
"health_checks": []
}' cargo run --bin tracker_checker
The HTTP Tracker client does not have any timeout so it will wait forever.
We have to add a timeout to the HTTP client requests:
/// HTTP Tracker Client
pub struct Client {
base_url: Url,
reqwest: ReqwestClient,
key: Option<Key>,
}
impl Client {
// ...
pub async fn announce(&self, query: &announce::Query) -> Response {
self.get(&self.build_announce_path_and_query(query)).await
}
pub async fn scrape(&self, query: &scrape::Query) -> Response {
self.get(&self.build_scrape_path_and_query(query)).await
}
pub async fn announce_with_header(&self, query: &Query, key: &str, value: &str) -> Response {
self.get_with_header(&self.build_announce_path_and_query(query), key, value)
.await
}
pub async fn health_check(&self) -> Response {
self.get(&self.build_path("health_check")).await
}
/// # Panics
///
/// This method fails if there was an error while sending request.
pub async fn get(&self, path: &str) -> Response {
self.reqwest.get(self.build_url(path)).send().await.unwrap()
}
/// # Panics
///
/// This method fails if there was an error while sending request.
pub async fn get_with_header(&self, path: &str, key: &str, value: &str) -> Response {
self.reqwest
.get(self.build_url(path))
.header(key, value)
.send()
.await
.unwrap()
}
// ...
}
You can add a timeout to all reqwest.get like this in the Health Check:
HttpClient::builder().timeout(Duration::from_secs(5)).build().unwrap();
You can force the error by adding a sleep in the handler:
async fn handle(
tracker: &Arc<Tracker>,
announce_request: &Announce,
client_ip_sources: &ClientIpSources,
maybe_key: Option<Key>,
) -> Response {
thread::sleep(time::Duration::from_secs(7));
let announce_data = match handle_announce(tracker, announce_request, client_ip_sources, maybe_key).await {
Ok(announce_data) => announce_data,
Err(error) => return error.into_response(),
};
build_response(announce_request, announce_data)
}
This issue should be implemented after refactoring the HTTP Tracker client to return errors instead of panicking.