zebra_network/
peer_cache_updater.rs1use std::io;
4
5use futures::FutureExt;
6use tokio::time::sleep;
7use tower::ServiceExt;
8
9use crate::{
10 address_book_updater::{AddressBookRequest, AddressBookResponse, AddressBookService},
11 constants::{DNS_LOOKUP_TIMEOUT, PEER_DISK_CACHE_UPDATE_INTERVAL},
12 meta_addr::MetaAddr,
13 BoxError, Config,
14};
15
16#[instrument(skip(config, address_book_service))]
18pub async fn peer_cache_updater(
19 config: Config,
20 mut address_book_service: AddressBookService,
21) -> Result<(), BoxError> {
22 sleep(DNS_LOOKUP_TIMEOUT * 4).await;
28
29 let mut wrote_cache = false;
30
31 loop {
32 wrote_cache |= update_peer_cache_once(&config, &mut address_book_service)
35 .await
36 .unwrap_or(false);
37
38 let interval = if wrote_cache {
42 PEER_DISK_CACHE_UPDATE_INTERVAL
43 } else {
44 DNS_LOOKUP_TIMEOUT * 4
45 };
46
47 sleep(interval).await;
48 }
49}
50
51pub async fn update_peer_cache_once(
56 config: &Config,
57 address_book_service: &mut AddressBookService,
58) -> io::Result<bool> {
59 let peer_list: std::collections::HashSet<_> = cacheable_peers(address_book_service)
60 .await?
61 .iter()
62 .map(|meta_addr| meta_addr.addr)
63 .collect();
64 let has_peers = !peer_list.is_empty();
65
66 config.update_peer_cache(peer_list).await?;
67
68 Ok(has_peers)
69}
70
71async fn cacheable_peers(
73 address_book_service: &mut AddressBookService,
74) -> io::Result<Vec<MetaAddr>> {
75 match address_book_service
79 .oneshot(AddressBookRequest::CacheablePeers)
80 .boxed()
81 .await
82 {
83 Ok(AddressBookResponse::Peers(peers)) => Ok(peers),
84 Ok(_) => unreachable!("CacheablePeers requests always return Peers"),
85 Err(error) => Err(io::Error::other(format!(
86 "error requesting cacheable peers, is Zebra shutting down? {error}"
87 ))),
88 }
89}