2022-04-15 12:09:24 -07:00
|
|
|
// Connect to future leaders with some jitter so the quic connection is warm
|
|
|
|
// by the time we need it.
|
|
|
|
|
|
|
|
use {
|
|
|
|
rand::{thread_rng, Rng},
|
|
|
|
solana_gossip::cluster_info::ClusterInfo,
|
|
|
|
solana_poh::poh_recorder::PohRecorder,
|
2022-08-24 09:47:02 -07:00
|
|
|
solana_tpu_client::{connection_cache::ConnectionCache, tpu_connection::TpuConnection},
|
2022-04-15 12:09:24 -07:00
|
|
|
std::{
|
|
|
|
sync::{
|
|
|
|
atomic::{AtomicBool, Ordering},
|
2022-07-05 07:29:44 -07:00
|
|
|
Arc, RwLock,
|
2022-04-15 12:09:24 -07:00
|
|
|
},
|
|
|
|
thread::{self, sleep, Builder, JoinHandle},
|
|
|
|
time::Duration,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
pub struct WarmQuicCacheService {
|
|
|
|
thread_hdl: JoinHandle<()>,
|
|
|
|
}
|
|
|
|
|
|
|
|
// ~50 seconds
|
|
|
|
const CACHE_OFFSET_SLOT: i64 = 100;
|
|
|
|
const CACHE_JITTER_SLOT: i64 = 20;
|
|
|
|
|
|
|
|
impl WarmQuicCacheService {
|
|
|
|
pub fn new(
|
2022-06-08 04:57:12 -07:00
|
|
|
connection_cache: Arc<ConnectionCache>,
|
2022-04-15 12:09:24 -07:00
|
|
|
cluster_info: Arc<ClusterInfo>,
|
2022-07-05 07:29:44 -07:00
|
|
|
poh_recorder: Arc<RwLock<PohRecorder>>,
|
2022-04-15 12:09:24 -07:00
|
|
|
exit: Arc<AtomicBool>,
|
|
|
|
) -> Self {
|
|
|
|
let thread_hdl = Builder::new()
|
2022-08-17 08:40:23 -07:00
|
|
|
.name("solWarmQuicSvc".to_string())
|
2022-04-15 12:09:24 -07:00
|
|
|
.spawn(move || {
|
|
|
|
let slot_jitter = thread_rng().gen_range(-CACHE_JITTER_SLOT, CACHE_JITTER_SLOT);
|
|
|
|
let mut maybe_last_leader = None;
|
|
|
|
while !exit.load(Ordering::Relaxed) {
|
2022-04-29 01:32:46 -07:00
|
|
|
let leader_pubkey = poh_recorder
|
2022-07-05 07:29:44 -07:00
|
|
|
.read()
|
2022-04-15 12:09:24 -07:00
|
|
|
.unwrap()
|
2022-04-29 01:32:46 -07:00
|
|
|
.leader_after_n_slots((CACHE_OFFSET_SLOT + slot_jitter) as u64);
|
|
|
|
if let Some(leader_pubkey) = leader_pubkey {
|
2022-04-15 12:09:24 -07:00
|
|
|
if maybe_last_leader
|
|
|
|
.map_or(true, |last_leader| last_leader != leader_pubkey)
|
|
|
|
{
|
|
|
|
maybe_last_leader = Some(leader_pubkey);
|
|
|
|
if let Some(addr) = cluster_info
|
|
|
|
.lookup_contact_info(&leader_pubkey, |leader| leader.tpu)
|
|
|
|
{
|
2022-06-08 04:57:12 -07:00
|
|
|
let conn = connection_cache.get_connection(&addr);
|
2022-05-26 08:21:16 -07:00
|
|
|
if let Err(err) = conn.send_wire_transaction(&[0u8]) {
|
2022-04-15 12:09:24 -07:00
|
|
|
warn!(
|
|
|
|
"Failed to warmup QUIC connection to the leader {:?}, Error {:?}",
|
|
|
|
leader_pubkey, err
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sleep(Duration::from_millis(200));
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.unwrap();
|
|
|
|
Self { thread_hdl }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn join(self) -> thread::Result<()> {
|
|
|
|
self.thread_hdl.join()
|
|
|
|
}
|
|
|
|
}
|