Skip to content

Commit 78c73b0

Browse files
committed
Avoid connection-per-RPC-call again by caching connections
In general, only one request will be in flight at a time in `lightning-block-sync`. Ideally we'd only have one connection, but without using the `futures` mutex type. Here we solve this narrowly for the one-request-at-a-time case by caching the connection and takeing the connection out of the cache while we work on it.
1 parent 6b55df9 commit 78c73b0

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

lightning-block-sync/src/rest.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,32 @@ use bitcoin::hashes::hex::ToHex;
99

1010
use std::convert::TryFrom;
1111
use std::convert::TryInto;
12+
use std::sync::Mutex;
1213

1314
/// A simple REST client for requesting resources using HTTP `GET`.
1415
pub struct RestClient {
1516
endpoint: HttpEndpoint,
17+
client: Mutex<Option<HttpClient>>,
1618
}
1719

1820
impl RestClient {
1921
/// Creates a new REST client connected to the given endpoint.
2022
///
2123
/// The endpoint should contain the REST path component (e.g., http://127.0.0.1:8332/rest).
2224
pub fn new(endpoint: HttpEndpoint) -> std::io::Result<Self> {
23-
Ok(Self { endpoint })
25+
Ok(Self { endpoint, client: Mutex::new(None) })
2426
}
2527

2628
/// Requests a resource encoded in `F` format and interpreted as type `T`.
2729
pub async fn request_resource<F, T>(&self, resource_path: &str) -> std::io::Result<T>
2830
where F: TryFrom<Vec<u8>, Error = std::io::Error> + TryInto<T, Error = std::io::Error> {
2931
let host = format!("{}:{}", self.endpoint.host(), self.endpoint.port());
3032
let uri = format!("{}/{}", self.endpoint.path().trim_end_matches("/"), resource_path);
31-
let mut client = HttpClient::connect(&self.endpoint)?;
32-
client.get::<F>(&uri, &host).await?.try_into()
33+
let mut client = if let Some(client) = self.client.lock().unwrap().take() { client }
34+
else { HttpClient::connect(&self.endpoint)? };
35+
let res = client.get::<F>(&uri, &host).await?.try_into();
36+
*self.client.lock().unwrap() = Some(client);
37+
res
3338
}
3439
}
3540

lightning-block-sync/src/rpc.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use crate::http::{HttpClient, HttpEndpoint, HttpError, JsonResponse};
77
use bitcoin::hash_types::BlockHash;
88
use bitcoin::hashes::hex::ToHex;
99

10+
use std::sync::Mutex;
11+
1012
use serde_json;
1113

1214
use std::convert::TryFrom;
@@ -39,6 +41,7 @@ impl Error for RpcError {}
3941
pub struct RpcClient {
4042
basic_auth: String,
4143
endpoint: HttpEndpoint,
44+
client: Mutex<Option<HttpClient>>,
4245
id: AtomicUsize,
4346
}
4447

@@ -50,6 +53,7 @@ impl RpcClient {
5053
Ok(Self {
5154
basic_auth: "Basic ".to_string() + credentials,
5255
endpoint,
56+
client: Mutex::new(None),
5357
id: AtomicUsize::new(0),
5458
})
5559
}
@@ -68,7 +72,8 @@ impl RpcClient {
6872
"id": &self.id.fetch_add(1, Ordering::AcqRel).to_string()
6973
});
7074

71-
let mut client = HttpClient::connect(&self.endpoint)?;
75+
let mut client = if let Some(client) = self.client.lock().unwrap().take() { client }
76+
else { HttpClient::connect(&self.endpoint)? };
7277
let mut response = match client.post::<JsonResponse>(&uri, &host, &self.basic_auth, content).await {
7378
Ok(JsonResponse(response)) => response,
7479
Err(e) if e.kind() == std::io::ErrorKind::Other => {
@@ -102,6 +107,7 @@ impl RpcClient {
102107
return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "expected JSON result"));
103108
}
104109

110+
*self.client.lock().unwrap() = Some(client);
105111
JsonResponse(result.take()).try_into()
106112
}
107113
}

0 commit comments

Comments
 (0)