be slightly more parsimonious with sending gossip

This commit is contained in:
Joe Ardent 2025-09-17 11:58:32 -07:00
parent 2badae0321
commit 6e9dfe881a

View file

@ -1,5 +1,5 @@
use std::{
collections::{HashMap, HashSet},
collections::{BTreeSet, HashMap, HashSet},
thread,
time::Duration,
};
@ -18,8 +18,7 @@ fn main() {
fn on_init(runner: &Runner) {
let tx = runner.get_backdoor();
thread::spawn(move || loop {
//let millis = rand::thread_rng().gen_range(200..=800);
let millis = 65;
let millis = 50;
thread::sleep(Duration::from_millis(millis));
let body = Body::from_type("do_gossip");
let msg = Message {
@ -32,8 +31,8 @@ fn on_init(runner: &Runner) {
#[derive(Clone, Default)]
struct BCaster {
store: HashSet<i64>,
gossips: HashMap<String, HashSet<i64>>,
store: BTreeSet<i64>,
gossips: HashMap<String, BTreeSet<i64>>,
neighbors: Vec<String>,
others: Vec<String>,
}
@ -52,26 +51,25 @@ impl BCaster {
fn gossip(&self, runner: &Runner) {
let mut rng = rand::thread_rng();
let rng = &mut rng;
for node in self.neighbors.iter() {
let mut goss = if let Some(neighbor) = self.gossips.get(node) {
self.store.difference(neighbor).cloned().collect()
} else {
self.store.clone()
};
for v in self.store.iter().filter(|_| rng.gen_bool(0.10)) {
goss.insert(*v);
}
if !goss.is_empty() && rng.gen_bool(0.6) {
let goss: Vec<_> = goss.into_iter().collect();
let payload: Payload = [("goss".to_string(), goss.into())].into_iter().collect();
let body = Body::from_type("gossip").with_payload(payload);
runner.send(node, body.clone());
}
}
let neighbor = &self.neighbors[rng.gen_range(0..self.neighbors.len())];
let goss = if let Some(ngoss) = self.gossips.get(neighbor) {
self.store.difference(ngoss).copied().collect()
} else {
self.store.clone()
};
let goss: Vec<_> = goss.into_iter().collect();
let payload: Payload = [("goss".to_string(), goss.into())].into_iter().collect();
let body = Body::from_type("gossip").with_payload(payload);
runner.send(neighbor, body);
// now the non-neighbor
let other = &self.others[rng.gen_range(0..self.others.len())];
let goss: Vec<_> = self.store.iter().cloned().collect();
let goss = if let Some(goss) = self.gossips.get(other) {
self.store.difference(goss).copied().collect()
} else {
self.store.clone()
};
let goss: Vec<_> = goss.into_iter().collect();
let payload: Payload = [("goss".to_string(), goss.into())].into_iter().collect();
let body = Body::from_type("gossip").with_payload(payload);
runner.send(other, body);
@ -88,10 +86,12 @@ impl Node for BCaster {
}
"broadcast" => {
let val = req.body.payload.get("message").and_then(|v| v.as_i64());
let sender = req.src.clone();
if let Some(val) = val {
self.store.insert(val);
let body = Body::from_type("broadcast_ok");
runner.reply(&req, body);
self.gossips.entry(sender).or_default().insert(val);
}
}
"read" => {