use rand::rngs::StdRng;
use std::{net::SocketAddr, num::NonZeroUsize, str::FromStr, time::Duration};
use foca::{Config, Foca, Identity, Member, PostcardCodec};
#[derive(Clone, PartialEq, Eq, Debug, serde::Serialize, serde::Deserialize)]
struct ID {
addr: SocketAddr,
bump: u64,
}
fn main() {
let wellknown = [
SocketAddr::from_str("192.168.0.100:8080").unwrap(),
SocketAddr::from_str("192.168.0.101:8080").unwrap(),
SocketAddr::from_str("192.168.0.102:8080").unwrap(),
];
let config = Config {
periodic_announce_to_down_members: Some(foca::PeriodicParams {
frequency: Duration::from_secs(60),
num_members: NonZeroUsize::new(3).unwrap(),
}),
remove_down_after: None,
..Config::simple()
};
let ourselves = ID::new(SocketAddr::from_str("192.168.0.200:8080").unwrap(), 1);
let mut runtime = foca::AccumulatingRuntime::new();
let rng: StdRng = rand::make_rng();
let mut foca = Foca::new(ourselves, config, rng, PostcardCodec);
foca.apply_many(
wellknown
.iter()
.copied()
.map(ID::wellknown)
.map(Member::down),
false,
&mut runtime,
)
.unwrap();
}
impl ID {
fn wellknown(addr: SocketAddr) -> Self {
Self { addr, bump: 0 }
}
fn new(addr: SocketAddr, bump: u64) -> Self {
assert_ne!(0, bump);
Self { addr, bump }
}
fn bump(&self) -> Self {
let bump = if self.bump == u64::MAX {
1
} else {
self.bump + 1
};
Self {
addr: self.addr,
bump,
}
}
}
impl Identity for ID {
type Addr = SocketAddr;
fn renew(&self) -> Option<Self> {
Some(self.bump())
}
fn addr(&self) -> Self::Addr {
self.addr
}
fn win_addr_conflict(&self, adversary: &Self) -> bool {
self.bump > adversary.bump
}
}