From 351b3e8a57c9e0143b7b6f3ed2160dcdce00225e Mon Sep 17 00:00:00 2001 From: Ellie Huxtable Date: Mon, 18 Sep 2023 08:39:19 +0100 Subject: [PATCH] Add connect timeout and overall timeout (#1238) * Add connect timeout and overall timeout * Make it configurable * Fix test * Add docs --- atuin-client/src/api_client.rs | 10 +++++++++- atuin-client/src/record/sync.rs | 14 ++++++++++++-- atuin-client/src/settings.rs | 5 +++++ atuin-client/src/sync.rs | 7 ++++++- atuin/src/command/client/account/delete.rs | 7 ++++++- atuin/src/command/client/sync/status.rs | 7 ++++++- atuin/tests/sync.rs | 2 +- docs/docs/config/config.md | 13 +++++++++++++ 8 files changed, 58 insertions(+), 7 deletions(-) diff --git a/atuin-client/src/api_client.rs b/atuin-client/src/api_client.rs index d2ca339fab0..b6625a341c3 100644 --- a/atuin-client/src/api_client.rs +++ b/atuin-client/src/api_client.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; use std::env; +use std::time::Duration; use eyre::{bail, Result}; use reqwest::{ @@ -106,7 +107,12 @@ pub async fn latest_version() -> Result { } impl<'a> Client<'a> { - pub fn new(sync_addr: &'a str, session_token: &'a str) -> Result { + pub fn new( + sync_addr: &'a str, + session_token: &'a str, + connect_timeout: u64, + timeout: u64, + ) -> Result { let mut headers = HeaderMap::new(); headers.insert(AUTHORIZATION, format!("Token {session_token}").parse()?); @@ -115,6 +121,8 @@ impl<'a> Client<'a> { client: reqwest::Client::builder() .user_agent(APP_USER_AGENT) .default_headers(headers) + .connect_timeout(Duration::new(connect_timeout, 0)) + .timeout(Duration::new(timeout, 0)) .build()?, }) } diff --git a/atuin-client/src/record/sync.rs b/atuin-client/src/record/sync.rs index ad9079ed463..56be0638eaa 100644 --- a/atuin-client/src/record/sync.rs +++ b/atuin-client/src/record/sync.rs @@ -22,7 +22,12 @@ pub enum Operation { } pub async fn diff(settings: &Settings, store: &mut impl Store) -> Result<(Vec, RecordIndex)> { - let client = Client::new(&settings.sync_address, &settings.session_token)?; + let client = Client::new( + &settings.sync_address, + &settings.session_token, + settings.network_connect_timeout, + settings.network_timeout, + )?; let local_index = store.tail_records().await?; let remote_index = client.record_index().await?; @@ -218,7 +223,12 @@ pub async fn sync_remote( local_store: &mut impl Store, settings: &Settings, ) -> Result<(i64, i64)> { - let client = Client::new(&settings.sync_address, &settings.session_token)?; + let client = Client::new( + &settings.sync_address, + &settings.session_token, + settings.network_connect_timeout, + settings.network_timeout, + )?; let mut uploaded = 0; let mut downloaded = 0; diff --git a/atuin-client/src/settings.rs b/atuin-client/src/settings.rs index e2d22e93bf6..e49ab0cb59f 100644 --- a/atuin-client/src/settings.rs +++ b/atuin-client/src/settings.rs @@ -176,6 +176,9 @@ pub struct Settings { pub workspaces: bool, pub ctrl_n_shortcuts: bool, + pub network_connect_timeout: u64, + pub network_timeout: u64, + // This is automatically loaded when settings is created. Do not set in // config! Keep secrets and settings apart. pub session_token: String, @@ -372,6 +375,8 @@ impl Settings { .set_default("workspaces", false)? .set_default("ctrl_n_shortcuts", false)? .set_default("secrets_filter", true)? + .set_default("network_connect_timeout", 5)? + .set_default("network_timeout", 30)? .add_source( Environment::with_prefix("atuin") .prefix_separator("_") diff --git a/atuin-client/src/sync.rs b/atuin-client/src/sync.rs index 439ed6d02ca..bd2ff474340 100644 --- a/atuin-client/src/sync.rs +++ b/atuin-client/src/sync.rs @@ -189,7 +189,12 @@ async fn sync_upload( } pub async fn sync(settings: &Settings, force: bool, db: &mut (impl Database + Send)) -> Result<()> { - let client = api_client::Client::new(&settings.sync_address, &settings.session_token)?; + let client = api_client::Client::new( + &settings.sync_address, + &settings.session_token, + settings.network_connect_timeout, + settings.network_timeout, + )?; let key = load_key(settings)?; // encryption key diff --git a/atuin/src/command/client/account/delete.rs b/atuin/src/command/client/account/delete.rs index e09f58a490c..5208a0773c0 100644 --- a/atuin/src/command/client/account/delete.rs +++ b/atuin/src/command/client/account/delete.rs @@ -9,7 +9,12 @@ pub async fn run(settings: &Settings) -> Result<()> { bail!("You are not logged in"); } - let client = api_client::Client::new(&settings.sync_address, &settings.session_token)?; + let client = api_client::Client::new( + &settings.sync_address, + &settings.session_token, + settings.network_connect_timeout, + settings.network_timeout, + )?; client.delete().await?; diff --git a/atuin/src/command/client/sync/status.rs b/atuin/src/command/client/sync/status.rs index b4aa3b7111e..7ff99553ad0 100644 --- a/atuin/src/command/client/sync/status.rs +++ b/atuin/src/command/client/sync/status.rs @@ -4,7 +4,12 @@ use colored::Colorize; use eyre::Result; pub async fn run(settings: &Settings, db: &impl Database) -> Result<()> { - let client = api_client::Client::new(&settings.sync_address, &settings.session_token)?; + let client = api_client::Client::new( + &settings.sync_address, + &settings.session_token, + settings.network_connect_timeout, + settings.network_timeout, + )?; let status = client.status().await?; let last_sync = Settings::last_sync()?; diff --git a/atuin/tests/sync.rs b/atuin/tests/sync.rs index 35aa35bba52..ab1eb420c60 100644 --- a/atuin/tests/sync.rs +++ b/atuin/tests/sync.rs @@ -77,7 +77,7 @@ async fn registration() { .await .unwrap(); - let client = api_client::Client::new(&address, ®istration_response.session).unwrap(); + let client = api_client::Client::new(&address, ®istration_response.session, 5, 30).unwrap(); // the session token works let status = client.status().await.unwrap(); diff --git a/docs/docs/config/config.md b/docs/docs/config/config.md index 5f54790c6e7..e0403d2a233 100644 --- a/docs/docs/config/config.md +++ b/docs/docs/config/config.md @@ -292,3 +292,16 @@ macOS does not have an Alt key, although terminal emulators can often # Use Ctrl-0 .. Ctrl-9 instead of Alt-0 .. Alt-9 UI shortcuts ctrl_n_shortcuts = true ``` + +## network_timeout +Default: 30 + +The max amount of time (in seconds) to wait for a network request. If any +operations with a sync server take longer than this, the code will fail - +rather than wait indefinitely. + +## network_connect_timeout +Default: 5 + +The max time (in seconds) we wait for a connection to become established with a +remote sync server. Any longer than this and the request will fail.