From b465318e12e4374d7e7cb3c00036fded340f155a Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 7 May 2021 22:40:22 +0000 Subject: [PATCH] Allow retrying HTTP requests if we hit a socket timeout --- lightning-block-sync/Cargo.toml | 2 +- lightning-block-sync/src/http.rs | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/lightning-block-sync/Cargo.toml b/lightning-block-sync/Cargo.toml index 6125874d..00208d78 100644 --- a/lightning-block-sync/Cargo.toml +++ b/lightning-block-sync/Cargo.toml @@ -16,7 +16,7 @@ rpc-client = [ "serde", "serde_json", "chunked_transfer" ] [dependencies] bitcoin = "0.26" lightning = { version = "0.0.14", path = "../lightning" } -tokio = { version = "1.0", features = [ "io-util", "net" ], optional = true } +tokio = { version = "1.0", features = [ "io-util", "net", "time" ], optional = true } serde = { version = "1.0", features = ["derive"], optional = true } serde_json = { version = "1.0", optional = true } chunked_transfer = { version = "1.4", optional = true } diff --git a/lightning-block-sync/src/http.rs b/lightning-block-sync/src/http.rs index f745e138..1f5f046c 100644 --- a/lightning-block-sync/src/http.rs +++ b/lightning-block-sync/src/http.rs @@ -158,16 +158,19 @@ impl HttpClient { let endpoint = self.stream.peer_addr().unwrap(); match self.send_request(request).await { Ok(bytes) => Ok(bytes), - Err(e) => match e.kind() { - std::io::ErrorKind::ConnectionReset | - std::io::ErrorKind::ConnectionAborted | - std::io::ErrorKind::UnexpectedEof => { - // Reconnect if the connection was closed. This may happen if the server's - // keep-alive limits are reached. - *self = Self::connect(endpoint)?; - self.send_request(request).await - }, - _ => Err(e), + Err(_) => { + // Reconnect and retry on fail. This can happen if the connection was closed after + // the keep-alive limits are reached, or generally if the request timed out due to + // Bitcoin Core being stuck on a long-running operation or its RPC queue being + // full. + // Block 100ms before retrying the request as in many cases the source of the error + // may be persistent for some time. + #[cfg(feature = "tokio")] + tokio::time::sleep(Duration::from_millis(100)).await; + #[cfg(not(feature = "tokio"))] + std::thread::sleep(Duration::from_millis(100)); + *self = Self::connect(endpoint)?; + self.send_request(request).await }, } } -- 2.30.2