node: sync project routing for known nodes
Keep the node's understanding of project hosting location current by updating how Inventory Announcement messages are processed. The Inventory Announcements contain a node's entire listing of projects. Replace the routing table information for the announcer with those from the message. Signed-off-by: Slack Coder <slackcoder@server.ky>
This commit is contained in:
parent
186eb42145
commit
a74cb416c1
|
|
@ -6,7 +6,7 @@ pub mod routing;
|
||||||
pub mod session;
|
pub mod session;
|
||||||
|
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::{fmt, net, net::IpAddr, str};
|
use std::{fmt, net, net::IpAddr, str};
|
||||||
|
|
@ -876,17 +876,23 @@ where
|
||||||
/// Process a peer inventory announcement by updating our routing table.
|
/// Process a peer inventory announcement by updating our routing table.
|
||||||
fn process_inventory(
|
fn process_inventory(
|
||||||
&mut self,
|
&mut self,
|
||||||
inventory: &Inventory,
|
inventory: &Vec<Id>,
|
||||||
from: NodeId,
|
from: NodeId,
|
||||||
timestamp: &Timestamp,
|
timestamp: &Timestamp,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
let mut included = HashSet::new();
|
||||||
for proj_id in inventory {
|
for proj_id in inventory {
|
||||||
// TODO: Fire an event on routing update.
|
included.insert(proj_id);
|
||||||
if self.routing.insert(*proj_id, from, *timestamp)? && self.config.is_tracking(proj_id)
|
if self.routing.insert(*proj_id, from, *timestamp)? && self.config.is_tracking(proj_id)
|
||||||
{
|
{
|
||||||
log::info!("Routing table updated for {} with seed {}", proj_id, from);
|
log::info!("Routing table updated for {} with seed {}", proj_id, from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for id in self.routing.get_resources(&from)?.into_iter() {
|
||||||
|
if !included.contains(&id) {
|
||||||
|
self.routing.remove(&id, &from)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,8 @@ impl Table {
|
||||||
pub trait Store {
|
pub trait Store {
|
||||||
/// Get the nodes seeding the given id.
|
/// Get the nodes seeding the given id.
|
||||||
fn get(&self, id: &Id) -> Result<HashSet<NodeId>, Error>;
|
fn get(&self, id: &Id) -> Result<HashSet<NodeId>, Error>;
|
||||||
|
/// Get the resources seeded by the given node.
|
||||||
|
fn get_resources(&self, node_id: &NodeId) -> Result<HashSet<Id>, Error>;
|
||||||
/// Get a specific entry.
|
/// Get a specific entry.
|
||||||
fn entry(&self, id: &Id, node: &NodeId) -> Result<Option<Timestamp>, Error>;
|
fn entry(&self, id: &Id, node: &NodeId) -> Result<Option<Timestamp>, Error>;
|
||||||
/// Add a new node seeding the given id.
|
/// Add a new node seeding the given id.
|
||||||
|
|
@ -83,6 +85,19 @@ impl Store for Table {
|
||||||
Ok(nodes)
|
Ok(nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_resources(&self, node: &NodeId) -> Result<HashSet<Id>, Error> {
|
||||||
|
let mut stmt = self
|
||||||
|
.db
|
||||||
|
.prepare("SELECT resource FROM routing WHERE node = ?")?;
|
||||||
|
stmt.bind(1, node)?;
|
||||||
|
|
||||||
|
let mut resources = HashSet::new();
|
||||||
|
for row in stmt.into_cursor() {
|
||||||
|
resources.insert(row?.get::<Id, _>("resource"));
|
||||||
|
}
|
||||||
|
Ok(resources)
|
||||||
|
}
|
||||||
|
|
||||||
fn entry(&self, id: &Id, node: &NodeId) -> Result<Option<Timestamp>, Error> {
|
fn entry(&self, id: &Id, node: &NodeId) -> Result<Option<Timestamp>, Error> {
|
||||||
let mut stmt = self
|
let mut stmt = self
|
||||||
.db
|
.db
|
||||||
|
|
@ -179,6 +194,26 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_insert_and_get_resources() {
|
||||||
|
let ids = arbitrary::set::<Id>(5..10);
|
||||||
|
let nodes = arbitrary::set::<NodeId>(5..10);
|
||||||
|
let mut db = Table::open(":memory:").unwrap();
|
||||||
|
|
||||||
|
for id in &ids {
|
||||||
|
for node in &nodes {
|
||||||
|
assert!(db.insert(*id, *node, 0).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for node in &nodes {
|
||||||
|
let projects = db.get_resources(node).unwrap();
|
||||||
|
for id in &ids {
|
||||||
|
assert!(projects.contains(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_entries() {
|
fn test_entries() {
|
||||||
let ids = arbitrary::set::<Id>(6..9);
|
let ids = arbitrary::set::<Id>(6..9);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue