urma_node/service/
overlay.rs1use super::Service;
4use crate::{
5 Error,
6 model::{BookEntry, OverlayStatus},
7 peer_discovery::Discovery,
8 peer_sync::{PeerSync, Scheduler},
9 recorded::{record, unix_seconds},
10};
11use std::sync::atomic::Ordering;
12
13impl Service {
14 pub fn with_peer_sync(mut self, sync: PeerSync) -> Result<Self, Error> {
17 self.peer_sync = Some(Scheduler::new(sync)?);
18 Ok(self)
19 }
20
21 pub fn with_discovery(mut self, discovery: Discovery) -> Result<Self, Error> {
24 self.discovery = Some(discovery);
25 Ok(self)
26 }
27
28 pub(super) fn discover_peers(&self) {
29 let Some(discovery) = &self.discovery else {
30 return;
31 };
32 if self.stop.load(Ordering::Acquire) {
33 return;
34 }
35 let result = self
36 .share_sync_backoff(discovery)
37 .and_then(|()| discovery.step(&self.engine, &self.stop));
38 if self.stop.load(Ordering::Acquire) {
39 return;
40 }
41 record(&self.discovery_error, &result);
42 }
43
44 fn share_sync_backoff(&self, discovery: &Discovery) -> Result<(), Error> {
47 let Some(scheduler) = &self.peer_sync else {
48 return Ok(());
49 };
50 discovery.hold_off(scheduler.backed_off(unix_seconds()?)?)
51 }
52
53 pub(super) fn sync_next_inventory(&self) {
54 let Some(scheduler) = &self.peer_sync else {
55 return;
56 };
57 if self.stop.load(Ordering::Acquire) {
58 return;
59 }
60 let result = self
61 .refresh_sync_peers(scheduler)
62 .and_then(|()| scheduler.step(&self.engine, &self.stop))
63 .and_then(|()| self.penalize_in_book(scheduler));
64 if self.stop.load(Ordering::Acquire) {
65 return;
66 }
67 record(&self.inventory_error, &result);
68 }
69
70 fn penalize_in_book(&self, scheduler: &Scheduler) -> Result<(), Error> {
73 let penalized = scheduler.drain_penalized()?;
74 match &self.discovery {
75 Some(discovery) => discovery.penalize(&penalized),
76 None => Ok(()),
77 }
78 }
79
80 fn refresh_sync_peers(&self, scheduler: &Scheduler) -> Result<(), Error> {
82 let Some(discovery) = &self.discovery else {
83 return Ok(());
84 };
85 let omitting = self.engine.omitting_peers()?;
86 scheduler.refresh(discovery.sync_sources(&omitting)?)
87 }
88
89 pub(super) fn overlay_status(&self) -> Result<Option<OverlayStatus>, Error> {
91 let Some(scheduler) = &self.peer_sync else {
92 return Ok(None);
93 };
94 let mut overlay = scheduler.status(&self.engine)?;
95 if let Some(discovery) = &self.discovery {
96 overlay.discovery = Some(discovery.status()?);
97 }
98 Ok(Some(overlay))
99 }
100
101 pub(super) fn overlay_book(&self) -> Result<Option<Vec<BookEntry>>, Error> {
103 self.discovery.as_ref().map(Discovery::book).transpose()
104 }
105}