p2panda_net/sync/
config.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use std::sync::Arc;
4
5use tokio::time::Duration;
6
7use p2panda_sync::{SyncProtocol, TopicQuery};
8
9const MAX_CONCURRENT_SYNC_SESSIONS: usize = 128;
10const MAX_RETRY_ATTEMPTS: u8 = 5;
11const RESYNC_INTERVAL: Duration = Duration::from_secs(60);
12const RESYNC_POLL_INTERVAL: Duration = Duration::from_secs(3);
13const RETRY_INTERVAL: Duration = Duration::from_secs(5);
14const RETRY_POLL_INTERVAL: Duration = Duration::from_secs(3);
15const SYNC_QUEUE_SEND_TIMEOUT: Duration = Duration::from_millis(100);
16pub(crate) const FALLBACK_RESYNC_INTERVAL_SEC: u64 = 3600;
17
18/// Configuration parameters for resync behaviour.
19#[derive(Clone, Debug)]
20pub struct ResyncConfiguration {
21    /// Minimum interval between resync attempts for a single peer-topic combination.
22    ///
23    /// Default: 60 seconds.
24    pub(crate) interval: Duration,
25
26    /// Minimum interval between each poll of the resync queue.
27    ///
28    /// Default: 3 second.
29    pub(crate) poll_interval: Duration,
30}
31
32impl ResyncConfiguration {
33    /// Return a default instance of `ResyncConfiguration`.
34    pub fn new() -> Self {
35        Default::default()
36    }
37
38    /// Define the minimum number of seconds between resync attempts for a single peer-topic
39    /// combination.
40    pub fn interval(mut self, seconds: u64) -> Self {
41        self.interval = Duration::from_secs(seconds);
42        self
43    }
44
45    /// Define the minimum number of seconds between poll of the resync queue.
46    pub fn poll_interval(mut self, seconds: u64) -> Self {
47        self.poll_interval = Duration::from_secs(seconds);
48        self
49    }
50}
51
52impl Default for ResyncConfiguration {
53    fn default() -> Self {
54        ResyncConfiguration {
55            interval: RESYNC_INTERVAL,
56            poll_interval: RESYNC_POLL_INTERVAL,
57        }
58    }
59}
60
61/// Configuration parameters for data synchronisation between peers.
62#[derive(Clone, Debug)]
63pub struct SyncConfiguration<T> {
64    protocol: Arc<dyn for<'a> SyncProtocol<'a, T> + 'static>,
65
66    /// Resync configuration (`None` represents no resync).
67    pub(crate) resync: Option<ResyncConfiguration>,
68
69    /// Maximum number of concurrent sync sessions.
70    ///
71    /// Default: 128.
72    pub(crate) max_concurrent_sync_sessions: usize,
73
74    /// Maximum number of attempts at successfully completing a sync session with a specific peer.
75    ///
76    /// Default: 5.
77    pub(crate) max_retry_attempts: u8,
78
79    /// Minimum interval between sync retry attempts (following a failed attempt).
80    ///
81    /// Default: 5 seconds.
82    pub(crate) retry_interval: Duration,
83
84    /// Minimum interval between each poll of the resync queue.
85    ///
86    /// Default: 3 seconds.
87    pub(crate) retry_poll_interval: Duration,
88
89    /// Maximum time to wait for sync attempt queue to have an open slot before failing.
90    ///
91    /// Default: 100 milliseconds.
92    pub(crate) sync_queue_send_timeout: Duration,
93}
94
95impl<T> SyncConfiguration<T>
96where
97    T: TopicQuery,
98{
99    /// Return a default instance of `SyncConfiguration`.
100    pub fn new(protocol: impl for<'a> SyncProtocol<'a, T> + 'static) -> Self {
101        Self {
102            protocol: Arc::new(protocol),
103            max_concurrent_sync_sessions: MAX_CONCURRENT_SYNC_SESSIONS,
104            max_retry_attempts: MAX_RETRY_ATTEMPTS,
105            resync: None,
106            retry_interval: RETRY_INTERVAL,
107            retry_poll_interval: RETRY_POLL_INTERVAL,
108            sync_queue_send_timeout: SYNC_QUEUE_SEND_TIMEOUT,
109        }
110    }
111
112    /// Define the maximum number of concurrent sync sessions.
113    pub fn max_concurrent_sync_sessions(mut self, sessions: usize) -> Self {
114        self.max_concurrent_sync_sessions = sessions;
115        self
116    }
117
118    /// Define the maximum number of attempts at successfully completing a sync session with a
119    /// specific peer.
120    pub fn max_retry_attempts(mut self, attempts: u8) -> Self {
121        self.max_retry_attempts = attempts;
122        self
123    }
124
125    /// Return the sync protocol from the given configuration.
126    pub fn protocol(&self) -> Arc<dyn for<'a> SyncProtocol<'a, T>> {
127        self.protocol.clone()
128    }
129
130    /// Provide the resync configuration for the sync scheduler.
131    pub fn resync(mut self, config: ResyncConfiguration) -> Self {
132        self.resync = Some(config);
133        self
134    }
135
136    /// Is resync enabled?
137    pub fn is_resync(&mut self) -> bool {
138        self.resync.is_some()
139    }
140
141    /// Define the minimum number of seconds between retry attempts for a single peer-topic
142    /// combination.
143    pub fn retry_interval(mut self, seconds: u64) -> Self {
144        self.retry_interval = Duration::from_secs(seconds);
145        self
146    }
147
148    /// Define the minimum number of seconds between poll of the retry queue.
149    pub fn retry_poll_interval(mut self, seconds: u64) -> Self {
150        self.retry_poll_interval = Duration::from_secs(seconds);
151        self
152    }
153
154    /// Define the maximum number of seconds to wait for sync attempt queue to have an open slot
155    /// before failing.
156    pub fn sync_queue_send_timeout(mut self, seconds: u64) -> Self {
157        self.sync_queue_send_timeout = Duration::from_secs(seconds);
158        self
159    }
160}