radicle: Announcer with replication factor of 0
Ensures that the Announcer will still announce to preferred seeds when the replication factor is 0.
This commit is contained in:
parent
4307eb35b5
commit
685c84e598
|
|
@ -182,14 +182,21 @@ impl Announcer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_target_reached(&self) -> Option<SuccessfulOutcome> {
|
fn is_target_reached(&self) -> Option<SuccessfulOutcome> {
|
||||||
|
// It should not be possible to construct a target that has no preferred
|
||||||
|
// seeds and set the target to 0
|
||||||
|
debug_assert!(self.target.has_preferred_seeds() || self.target.has_replication_factor());
|
||||||
|
|
||||||
let SuccessCounts { preferred, synced } = self.success_counts();
|
let SuccessCounts { preferred, synced } = self.success_counts();
|
||||||
if !self.target.preferred_seeds.is_empty() && preferred >= self.target.preferred_seeds.len()
|
if self.target.has_preferred_seeds() && preferred >= self.target.preferred_seeds.len() {
|
||||||
{
|
|
||||||
Some(SuccessfulOutcome::PreferredNodes {
|
Some(SuccessfulOutcome::PreferredNodes {
|
||||||
preferred: self.target.preferred_seeds.len(),
|
preferred: self.target.preferred_seeds.len(),
|
||||||
total_nodes_synced: synced,
|
total_nodes_synced: synced,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
|
// The only target to hit is preferred seeds
|
||||||
|
if !self.target.has_replication_factor() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
let replicas = self.target.replicas();
|
let replicas = self.target.replicas();
|
||||||
let min = replicas.lower_bound();
|
let min = replicas.lower_bound();
|
||||||
match replicas.upper_bound() {
|
match replicas.upper_bound() {
|
||||||
|
|
@ -526,6 +533,16 @@ impl Target {
|
||||||
pub fn replicas(&self) -> &ReplicationFactor {
|
pub fn replicas(&self) -> &ReplicationFactor {
|
||||||
&self.replicas
|
&self.replicas
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the target has preferred seeds
|
||||||
|
pub fn has_preferred_seeds(&self) -> bool {
|
||||||
|
!self.preferred_seeds.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check that lower bound of the replication is greater than `0`
|
||||||
|
pub fn has_replication_factor(&self) -> bool {
|
||||||
|
self.replicas.lower_bound() != 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
|
@ -912,6 +929,48 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn announcer_with_replication_factor_zero_and_preferred_seeds() {
|
||||||
|
let local = arbitrary::gen::<NodeId>(0);
|
||||||
|
let seeds = arbitrary::set::<NodeId>(5..=5);
|
||||||
|
|
||||||
|
let preferred_seeds = seeds.iter().take(2).copied().collect::<BTreeSet<_>>();
|
||||||
|
let unsynced = seeds.iter().skip(2).copied().collect::<BTreeSet<_>>();
|
||||||
|
|
||||||
|
// Zero replication factor but with preferred seeds should work
|
||||||
|
let config = AnnouncerConfig::public(
|
||||||
|
local,
|
||||||
|
// Zero replication factor
|
||||||
|
ReplicationFactor::must_reach(0),
|
||||||
|
preferred_seeds.clone(),
|
||||||
|
BTreeSet::new(),
|
||||||
|
unsynced,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut announcer = Announcer::new(config).unwrap();
|
||||||
|
|
||||||
|
// Should succeed immediately when we sync with all preferred seeds
|
||||||
|
for &node in &preferred_seeds {
|
||||||
|
let duration = time::Duration::from_secs(1);
|
||||||
|
match announcer.synced_with(node, duration) {
|
||||||
|
ControlFlow::Continue(_) => {} // Continue until all preferred are synced
|
||||||
|
ControlFlow::Break(success) => {
|
||||||
|
assert_eq!(
|
||||||
|
success.outcome(),
|
||||||
|
SuccessfulOutcome::PreferredNodes {
|
||||||
|
preferred: preferred_seeds.len(),
|
||||||
|
total_nodes_synced: preferred_seeds.len()
|
||||||
|
},
|
||||||
|
"Should succeed with preferred seeds even with zero replication factor"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("Should have succeeded with preferred seeds");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cannot_construct_announcer() {
|
fn cannot_construct_announcer() {
|
||||||
let local = arbitrary::gen::<NodeId>(0);
|
let local = arbitrary::gen::<NodeId>(0);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue