Skip to content

Commit 010011a

Browse files
committed
Move network graph persistence to its own tokio task
The DB persistence loop is responsible for taking new gossip off of the persistence queue and writing it to Postgres. If it gets stalled, the logic pushing gossip onto the event queue might also stall. To reduce the dependence of that on taking the `NetworkGraph` mutexes and writing the full, large, graph to disk, move it to its own task.
1 parent 05d5420 commit 010011a

2 files changed

Lines changed: 30 additions & 30 deletions

File tree

src/lib.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ extern crate core;
1111

1212
use std::collections::{HashMap, HashSet};
1313
use std::fs::File;
14-
use std::io::BufReader;
14+
use std::io::{BufReader, BufWriter, Write};
1515
use std::ops::Deref;
1616
use std::sync::Arc;
17+
use std::time::Duration;
1718
use bitcoin::blockdata::constants::ChainHash;
1819
use lightning::log_info;
1920

@@ -104,7 +105,7 @@ impl<L: Deref + Clone + Send + Sync + 'static> RapidSyncProcessor<L> where L::Ta
104105

105106
if config::DOWNLOAD_NEW_GOSSIP {
106107
let (mut persister, persistence_sender) =
107-
GossipPersister::new(self.network_graph.clone(), self.logger.clone()).await;
108+
GossipPersister::new(self.logger.clone()).await;
108109
log_info!(self.logger, "Starting gossip db persistence listener");
109110
tokio::spawn(async move { persister.persist_gossip().await; });
110111

@@ -130,6 +131,16 @@ impl<L: Deref + Clone + Send + Sync + 'static> RapidSyncProcessor<L> where L::Ta
130131
log_info!(self.logger, "Starting gossip download");
131132
tokio::spawn(tracking::download_gossip(persistence_sender, sync_completion_sender,
132133
Arc::clone(&self.network_graph), self.logger.clone()));
134+
135+
let graph = Arc::clone(&self.network_graph);
136+
let logger = self.logger.clone();
137+
tokio::spawn(async move {
138+
let mut intvl = tokio::time::interval(Duration::from_secs(60 * 10));
139+
loop {
140+
intvl.tick().await;
141+
persist_network_graph(&logger, &*graph);
142+
}
143+
});
133144
} else {
134145
sync_completion_sender.send(()).await.unwrap();
135146
}
@@ -145,6 +156,22 @@ impl<L: Deref + Clone + Send + Sync + 'static> RapidSyncProcessor<L> where L::Ta
145156
}
146157
}
147158

159+
fn persist_network_graph<L: Deref>(logger: &L, graph: &NetworkGraph<L>) where L::Target: Logger {
160+
log_info!(logger, "Caching network graph…");
161+
let cache_path = config::network_graph_cache_path();
162+
let file = std::fs::OpenOptions::new()
163+
.create(true)
164+
.write(true)
165+
.truncate(true)
166+
.open(&cache_path)
167+
.unwrap();
168+
graph.remove_stale_channels_and_tracking();
169+
let mut writer = BufWriter::new(file);
170+
graph.write(&mut writer).unwrap();
171+
writer.flush().unwrap();
172+
log_info!(logger, "Cached network graph!");
173+
}
174+
148175
pub(crate) async fn connect_to_db() -> Client {
149176
let connection_config = config::db_connection_config();
150177
let (client, connection) = connection_config.connect(NoTls).await.unwrap();

src/persistence.rs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
use std::fs::OpenOptions;
2-
use std::io::{BufWriter, Write};
31
use std::ops::Deref;
42
use std::sync::Arc;
53
use std::time::{Duration, Instant};
64
use lightning::log_info;
7-
use lightning::routing::gossip::NetworkGraph;
85
use lightning::util::logger::Logger;
96
use lightning::util::ser::Writeable;
107
use tokio::runtime::Runtime;
@@ -18,13 +15,12 @@ const INSERT_PARALELLISM: usize = 16;
1815

1916
pub(crate) struct GossipPersister<L: Deref> where L::Target: Logger {
2017
gossip_persistence_receiver: mpsc::Receiver<GossipMessage>,
21-
network_graph: Arc<NetworkGraph<L>>,
2218
tokio_runtime: Runtime,
2319
logger: L
2420
}
2521

2622
impl<L: Deref + Clone + Send + Sync + 'static> GossipPersister<L> where L::Target: Logger {
27-
pub async fn new(network_graph: Arc<NetworkGraph<L>>, logger: L) -> (Self, mpsc::Sender<GossipMessage>) {
23+
pub async fn new(logger: L) -> (Self, mpsc::Sender<GossipMessage>) {
2824
{ // initialize the database
2925
// this client instance is only used once
3026
let mut client = crate::connect_to_db().await;
@@ -86,7 +82,6 @@ impl<L: Deref + Clone + Send + Sync + 'static> GossipPersister<L> where L::Targe
8682
let runtime = Runtime::new().unwrap();
8783
(GossipPersister {
8884
gossip_persistence_receiver,
89-
network_graph,
9085
tokio_runtime: runtime,
9186
logger
9287
}, gossip_persistence_sender)
@@ -96,7 +91,6 @@ impl<L: Deref + Clone + Send + Sync + 'static> GossipPersister<L> where L::Targe
9691
// print log statement every minute
9792
let mut latest_persistence_log = Instant::now() - Duration::from_secs(60);
9893
let mut i = 0u32;
99-
let mut latest_graph_cache_time = Instant::now();
10094
let insert_limiter = Arc::new(Semaphore::new(INSERT_PARALELLISM));
10195
let connections_cache = Arc::new(Mutex::new(Vec::with_capacity(INSERT_PARALELLISM)));
10296
#[cfg(test)]
@@ -112,11 +106,6 @@ impl<L: Deref + Clone + Send + Sync + 'static> GossipPersister<L> where L::Targe
112106
latest_persistence_log = Instant::now();
113107
}
114108

115-
// has it been ten minutes? Just cache it
116-
if latest_graph_cache_time.elapsed().as_secs() >= 600 {
117-
self.persist_network_graph();
118-
latest_graph_cache_time = Instant::now();
119-
}
120109
insert_limiter.acquire().await.unwrap().forget();
121110

122111
let limiter_ref = Arc::clone(&insert_limiter);
@@ -309,20 +298,4 @@ impl<L: Deref + Clone + Send + Sync + 'static> GossipPersister<L> where L::Targe
309298
task.await.unwrap();
310299
}
311300
}
312-
313-
fn persist_network_graph(&self) {
314-
log_info!(self.logger, "Caching network graph…");
315-
let cache_path = config::network_graph_cache_path();
316-
let file = OpenOptions::new()
317-
.create(true)
318-
.write(true)
319-
.truncate(true)
320-
.open(&cache_path)
321-
.unwrap();
322-
self.network_graph.remove_stale_channels_and_tracking();
323-
let mut writer = BufWriter::new(file);
324-
self.network_graph.write(&mut writer).unwrap();
325-
writer.flush().unwrap();
326-
log_info!(self.logger, "Cached network graph!");
327-
}
328301
}

0 commit comments

Comments
 (0)