Skip to content

Commit

Permalink
Merge #482: Index API client: add timeout to requests
Browse files Browse the repository at this point in the history
47f5242 chore: fix comment (Jose Celano)
3d3fc2d chore: add todo to seeder (Jose Celano)
2fc2016 refactor: [#472] move unwraps from API client up (Jose Celano)
1015945 chore: remove comment (Jose Celano)
564df07 docs: move comment (Jose Celano)
a8c2f84 refactor: [#472] move unwraps from generic HTTP client up to Index API client (Jose Celano)
26422fc feat: [#472] add timeout to API client requests (Jose Celano)
9ff4de4 feat: [#472] inject URL scheme in API client (Jose Celano)
2cf5f47 refactor: [#472] move generic HTTP client (Jose Celano)

Pull request description:

  The API client does not have any timeout. The client waits indefinitely for responses. That should not be the default behaviour. It should return an error after a timeout. The users using the client should handle the timeout or any other error.

  ### Subtasks

  - [x] Move generic HTTP client to HTTP mod.
  - [x] Generic HTTP client: Inject the scheme part of the URL in the constructor.
  - [x] Add timeouts to the generic HTTP client.
  - [x] Remove `unwraps` from the generic HTTP client. Return errors.
  - [x] Remove `unwraps` from the Index API HTTP client. Return errors.

ACKs for top commit:
  josecelano:
    ACK 47f5242

Tree-SHA512: 59cc901b58c19aff0f5258a5297d722389beb9d1ac38838fc470e9cc3e2159abc594cb05db7c1403e2111477149c1834a68f182425cbc101bc0c29c2d0b76613
  • Loading branch information
josecelano committed Feb 9, 2024
2 parents 465c853 + 47f5242 commit 5a854f9
Show file tree
Hide file tree
Showing 7 changed files with 506 additions and 241 deletions.
18 changes: 15 additions & 3 deletions src/console/commands/seeder/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ pub async fn upload_torrent(client: &Client, upload_torrent_form: UploadTorrentM
add_category(client, &upload_torrent_form.category).await;
}

let response = client.upload_torrent(upload_torrent_form.into()).await;
// todo: if we receive timeout error we should retry later. Otherwise we
// have to restart the seeder manually.

let response = client
.upload_torrent(upload_torrent_form.into())
.await
.expect("API should return a response");

debug!(target:"seeder", "response: {}", response.status);

Expand Down Expand Up @@ -68,7 +74,8 @@ pub async fn login(client: &Client, username: &str, password: &str) -> LoggedInU
login: username.to_owned(),
password: password.to_owned(),
})
.await;
.await
.expect("API should return a response");

let res: SuccessfulLoginResponse = serde_json::from_str(&response.body).unwrap_or_else(|_| {
panic!(
Expand All @@ -86,21 +93,26 @@ pub async fn login(client: &Client, username: &str, password: &str) -> LoggedInU
///
/// Panics if the response body is not a valid JSON.
pub async fn get_categories(client: &Client) -> Vec<ListItem> {
let response = client.get_categories().await;
let response = client.get_categories().await.expect("API should return a response");

let res: ListResponse = serde_json::from_str(&response.body).unwrap();

res.data
}

/// It adds a new category.
///
/// # Panics
///
/// Will panic if it doesn't get a response form the API.
pub async fn add_category(client: &Client, name: &str) -> TextResponse {
client
.add_category(AddCategoryForm {
name: name.to_owned(),
icon: None,
})
.await
.expect("API should return a response")
}

/// It checks if the category list contains the given category.
Expand Down
12 changes: 8 additions & 4 deletions src/console/commands/seeder/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
//!
//! ```text
//! cargo run --bin seeder -- \
//! --api-base-url "localhost:3001" \
//! --api-base-url "http://localhost:3001" \
//! --number-of-torrents 1000 \
//! --user admin \
//! --password 12345678 \
Expand Down Expand Up @@ -127,12 +127,14 @@
//!
//! As you can see the `info` dictionary is exactly the same, which produces
//! the same info-hash for the torrent.
use std::str::FromStr;
use std::thread::sleep;
use std::time::Duration;

use anyhow::Context;
use clap::Parser;
use log::{debug, info, LevelFilter};
use reqwest::Url;
use text_colorizer::Colorize;
use uuid::Uuid;

Expand Down Expand Up @@ -173,9 +175,11 @@ pub async fn run() -> anyhow::Result<()> {

let args = Args::parse();

let api_user = login_index_api(&args.api_base_url, &args.user, &args.password).await;
let api_url = Url::from_str(&args.api_base_url).context("failed to parse API base URL")?;

let api_client = Client::authenticated(&args.api_base_url, &api_user.token);
let api_user = login_index_api(&api_url, &args.user, &args.password).await;

let api_client = Client::authenticated(&api_url, &api_user.token);

info!(target:"seeder", "Uploading { } random torrents to the Torrust Index with a { } seconds interval...", args.number_of_torrents.to_string().yellow(), args.interval.to_string().yellow());

Expand All @@ -202,7 +206,7 @@ pub async fn run() -> anyhow::Result<()> {
}

/// It logs in a user in the Index API.
pub async fn login_index_api(api_url: &str, username: &str, password: &str) -> LoggedInUserData {
pub async fn login_index_api(api_url: &Url, username: &str, password: &str) -> LoggedInUserData {
let unauthenticated_client = Client::unauthenticated(api_url);

info!(target:"seeder", "Trying to login with username: {} ...", username.yellow());
Expand Down
Loading

0 comments on commit 5a854f9

Please sign in to comment.