referrerpolicy=no-referrer-when-downgrade

sc_authority_discovery/
interval.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19use futures::{future::FutureExt, ready, stream::Stream};
20use futures_timer::Delay;
21use std::{
22	pin::Pin,
23	task::{Context, Poll},
24	time::Duration,
25};
26
27/// Exponentially increasing interval
28///
29/// Doubles interval duration on each tick until the configured maximum is reached.
30pub struct ExpIncInterval {
31	start: Duration,
32	max: Duration,
33	next: Duration,
34	delay: Delay,
35}
36
37impl ExpIncInterval {
38	/// Create a new [`ExpIncInterval`].
39	pub fn new(start: Duration, max: Duration) -> Self {
40		let delay = Delay::new(start);
41		Self { start, max, next: start * 2, delay }
42	}
43
44	/// Fast forward the exponentially increasing interval to the configured maximum, if not already
45	/// set.
46	pub fn set_to_max(&mut self) {
47		if self.next == self.max {
48			return;
49		}
50
51		self.next = self.max;
52		self.delay = Delay::new(self.next);
53	}
54
55	/// Rewind the exponentially increasing interval to the configured start, if not already set.
56	pub fn set_to_start(&mut self) {
57		if self.next == self.start * 2 {
58			return;
59		}
60
61		self.next = self.start * 2;
62		self.delay = Delay::new(self.start);
63	}
64}
65
66impl Stream for ExpIncInterval {
67	type Item = ();
68
69	fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
70		ready!(self.delay.poll_unpin(cx));
71		self.delay = Delay::new(self.next);
72		self.next = std::cmp::min(self.max, self.next * 2);
73
74		Poll::Ready(Some(()))
75	}
76}