From 06e00be985298c6241f736907cd683b9e4117dc2 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 26 Aug 2020 18:30:51 +1000 Subject: [PATCH] specify I/O timeout We need to be a bit conservative here due to buffer bloat - in the upload case on a slow link, it can appear that no I/O is happening when a buffer is draining. --- rslib/src/media/sync.rs | 8 +++++--- rslib/src/sync/http_client.rs | 23 +++++++++++++++++++++-- rslib/src/sync/mod.rs | 1 + 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/rslib/src/media/sync.rs b/rslib/src/media/sync.rs index 6bbb856fc..145475720 100644 --- a/rslib/src/media/sync.rs +++ b/rslib/src/media/sync.rs @@ -8,7 +8,7 @@ use crate::media::files::{ add_file_from_ankiweb, data_for_file, mtime_as_i64, normalize_filename, AddedFile, }; use crate::media::MediaManager; -use crate::version; +use crate::{sync::Timeouts, version}; use bytes::Bytes; use reqwest::{multipart, Client, Response}; use serde_derive::{Deserialize, Serialize}; @@ -155,9 +155,11 @@ where host_number: u32, log: Logger, ) -> MediaSyncer<'_, P> { + let timeouts = Timeouts::new(); let client = Client::builder() - .connect_timeout(Duration::from_secs(30)) - .timeout(Duration::from_secs(60)) + .connect_timeout(Duration::from_secs(timeouts.connect_secs)) + .timeout(Duration::from_secs(timeouts.request_secs)) + .io_timeout(Duration::from_secs(timeouts.io_secs)) .build() .unwrap(); let endpoint = media_sync_endpoint(host_number); diff --git a/rslib/src/sync/http_client.rs b/rslib/src/sync/http_client.rs index 7b2ce9f00..04fb67c75 100644 --- a/rslib/src/sync/http_client.rs +++ b/rslib/src/sync/http_client.rs @@ -72,14 +72,33 @@ struct SanityCheckIn { full: bool, } +pub struct Timeouts { + pub connect_secs: u64, + pub request_secs: u64, + pub io_secs: u64, +} + +impl Timeouts { + pub fn new() -> Self { + Timeouts { + connect_secs: 30, + /// This is smaller than the I/O limit because it is just a + /// default - some longer-running requests override it. + request_secs: 60, + io_secs: 300, + } + } +} #[derive(Serialize)] struct Empty {} impl HTTPSyncClient { pub fn new(hkey: Option, host_number: u32) -> HTTPSyncClient { + let timeouts = Timeouts::new(); let client = Client::builder() - .connect_timeout(Duration::from_secs(30)) - .timeout(Duration::from_secs(60)) + .connect_timeout(Duration::from_secs(timeouts.connect_secs)) + .timeout(Duration::from_secs(timeouts.request_secs)) + .io_timeout(Duration::from_secs(timeouts.io_secs)) .build() .unwrap(); let skey = guid(); diff --git a/rslib/src/sync/mod.rs b/rslib/src/sync/mod.rs index facdfe7a7..cfe31a802 100644 --- a/rslib/src/sync/mod.rs +++ b/rslib/src/sync/mod.rs @@ -21,6 +21,7 @@ use flate2::write::GzEncoder; use flate2::Compression; use futures::StreamExt; use http_client::HTTPSyncClient; +pub use http_client::Timeouts; use itertools::Itertools; use reqwest::{multipart, Client, Response}; use serde::{de::DeserializeOwned, Deserialize, Serialize};