1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// Copyright 2025 The Tari Project
// SPDX-License-Identifier: BSD-3-Clause
//! Async-safe access to the (synchronous) peer database.
//!
//! Every peer database call ultimately runs diesel/r2d2 against SQLite, which is *blocking*: it
//! waits on an r2d2 pool checkout and then on SQLite's own single-writer lock. Calling that
//! directly from an `async fn` does not park a task, it parks the tokio **worker thread** running
//! that task. Under sustained peer-database write pressure the worker pool drains one thread at a
//! time until the comms actors (`ConnectionManager`, `Dialer`, `ConnectivityManager`) stop being
//! scheduled at all - the node keeps its TCP connections but can no longer dial or propagate.
//!
//! [`BlockingPeerStorage`] exists to make that mistake unrepresentable: it owns the only
//! [`PeerStorageSql`] handle, never hands it out, and the sole way to reach it is
//! [`BlockingPeerStorage::call`], which moves the work onto `tokio::task::spawn_blocking`.
use task;
use crate;
/// Owns the peer database handle and only ever touches it from the blocking thread pool.
///
/// The inner [`PeerStorageSql`] is deliberately private with no accessor. Adding a synchronous peer
/// database call to [`PeerManager`](crate::peer_manager::PeerManager) therefore does not compile
/// unless it goes through [`Self::call`].
pub