Skip to content

Commit 7945af7

Browse files
committed
[block-sync] Don't hold client-cache lock while connecting
`lightning-block-sync`'s REST and RPC clients both hold a cache for a connected client to avoid the extra connection round-trip on each request. Because only one client can be using a connection at once, the connection is `take()`n out of an `Option` behind a `Mutex` and if there isn't one present, we call `HttpClient::connect` to build a new one. However, this full logic is completed in one statement, causing a client-cache lock to be held during `HttpClient::connect`. This can turn into quite a bit of contention when using these clients as gossip verifiers as we can create many requests back-to-back during startup. I noticed this as my node during startup only seemed to be saturating one core and managed to get a backtrace that showed several threads being blocked on this mutex when hitting a Bitcoin Core node over REST that is on the same LAN, but not the same machine.
1 parent 9ce3dd5 commit 7945af7

File tree

2 files changed

+4
-2
lines changed

2 files changed

+4
-2
lines changed

lightning-block-sync/src/rest.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ impl RestClient {
3434
{
3535
let host = format!("{}:{}", self.endpoint.host(), self.endpoint.port());
3636
let uri = format!("{}/{}", self.endpoint.path().trim_end_matches("/"), resource_path);
37-
let mut client = if let Some(client) = self.client.lock().unwrap().take() {
37+
let reserved_client = self.client.lock().unwrap().take();
38+
let mut client = if let Some(client) = reserved_client {
3839
client
3940
} else {
4041
HttpClient::connect(&self.endpoint)?

lightning-block-sync/src/rpc.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ impl RpcClient {
7777
"id": &self.id.fetch_add(1, Ordering::AcqRel).to_string()
7878
});
7979

80-
let mut client = if let Some(client) = self.client.lock().unwrap().take() {
80+
let reserved_client = self.client.lock().unwrap().take();
81+
let mut client = if let Some(client) = reserved_client {
8182
client
8283
} else {
8384
HttpClient::connect(&self.endpoint)?

0 commit comments

Comments
 (0)