Allow retrying HTTP requests if we hit a socket timeout
authorMatt Corallo <git@bluematt.me>
Fri, 7 May 2021 22:40:22 +0000 (22:40 +0000)
committerMatt Corallo <git@bluematt.me>
Mon, 10 May 2021 16:55:09 +0000 (16:55 +0000)
lightning-block-sync/Cargo.toml
lightning-block-sync/src/http.rs

index 6125874d963eadea1c5be3bc905a0540abe6f030..00208d78b9b09b7db39259b589ea68959c4db7ee 100644 (file)
@@ -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 }
index f745e138fb915eddff035d814ff62de1ab05c9e8..1f5f046c0f87dd904820e7f97718b1a3ba16ac15 100644 (file)
@@ -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
                        },
                }
        }