node: Fix filter construction and policy code
This commit is contained in:
parent
27d0c8f235
commit
2f1a18470e
|
|
@ -249,6 +249,12 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the next i/o action to execute.
|
||||||
|
#[allow(clippy::should_implement_trait)]
|
||||||
|
pub fn next(&mut self) -> Option<reactor::Io> {
|
||||||
|
self.reactor.next()
|
||||||
|
}
|
||||||
|
|
||||||
/// Track a repository.
|
/// Track a repository.
|
||||||
/// Returns whether or not the tracking policy was updated.
|
/// Returns whether or not the tracking policy was updated.
|
||||||
pub fn track_repo(&mut self, id: &Id, scope: tracking::Scope) -> Result<bool, tracking::Error> {
|
pub fn track_repo(&mut self, id: &Id, scope: tracking::Scope) -> Result<bool, tracking::Error> {
|
||||||
|
|
@ -267,8 +273,14 @@ where
|
||||||
// Nb. This is potentially slow if we have lots of projects. We should probably
|
// Nb. This is potentially slow if we have lots of projects. We should probably
|
||||||
// only re-compute the filter when we've untracked a certain amount of projects
|
// only re-compute the filter when we've untracked a certain amount of projects
|
||||||
// and the filter is really out of date.
|
// and the filter is really out of date.
|
||||||
self.filter = Filter::new(self.tracking.repo_entries()?.map(|(e, _)| e));
|
//
|
||||||
|
// TODO: Share this code with initialization code.
|
||||||
|
self.filter = Filter::new(
|
||||||
|
self.tracking
|
||||||
|
.repo_entries()?
|
||||||
|
.filter(|(_, _, policy)| *policy == tracking::Policy::Track)
|
||||||
|
.map(|(e, _, _)| e),
|
||||||
|
);
|
||||||
Ok(updated)
|
Ok(updated)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -345,7 +357,12 @@ where
|
||||||
self.routing.insert(id, self.node_id(), time.as_secs())?;
|
self.routing.insert(id, self.node_id(), time.as_secs())?;
|
||||||
}
|
}
|
||||||
// Setup subscription filter for tracked repos.
|
// Setup subscription filter for tracked repos.
|
||||||
self.filter = Filter::new(self.tracking.repo_entries()?.map(|(e, _)| e));
|
self.filter = Filter::new(
|
||||||
|
self.tracking
|
||||||
|
.repo_entries()?
|
||||||
|
.filter(|(_, _, policy)| *policy == tracking::Policy::Track)
|
||||||
|
.map(|(e, _, _)| e),
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -586,6 +603,8 @@ where
|
||||||
// For outbound connections, we are the first to say "Hello".
|
// For outbound connections, we are the first to say "Hello".
|
||||||
// For inbound connections, we wait for the remote to say "Hello" first.
|
// For inbound connections, we wait for the remote to say "Hello" first.
|
||||||
if link.is_outbound() {
|
if link.is_outbound() {
|
||||||
|
let filter = self.filter();
|
||||||
|
|
||||||
if let Some(peer) = self.sessions.get_mut(&remote) {
|
if let Some(peer) = self.sessions.get_mut(&remote) {
|
||||||
self.reactor.write_all(
|
self.reactor.write_all(
|
||||||
remote,
|
remote,
|
||||||
|
|
@ -593,7 +612,7 @@ where
|
||||||
self.clock.as_secs(),
|
self.clock.as_secs(),
|
||||||
&self.storage,
|
&self.storage,
|
||||||
&self.signer,
|
&self.signer,
|
||||||
self.filter.clone(),
|
filter,
|
||||||
&self.config,
|
&self.config,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -833,6 +852,7 @@ where
|
||||||
remote: &NodeId,
|
remote: &NodeId,
|
||||||
message: Message,
|
message: Message,
|
||||||
) -> Result<(), session::Error> {
|
) -> Result<(), session::Error> {
|
||||||
|
let filter = self.filter(); // TODO: Don't call this if it's not used.
|
||||||
let Some(peer) = self.sessions.get_mut(remote) else {
|
let Some(peer) = self.sessions.get_mut(remote) else {
|
||||||
return Err(session::Error::NotFound(*remote));
|
return Err(session::Error::NotFound(*remote));
|
||||||
};
|
};
|
||||||
|
|
@ -871,7 +891,7 @@ where
|
||||||
self.clock.as_secs(),
|
self.clock.as_secs(),
|
||||||
&self.storage,
|
&self.storage,
|
||||||
&self.signer,
|
&self.signer,
|
||||||
self.filter.clone(),
|
filter,
|
||||||
&self.config,
|
&self.config,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -1053,6 +1073,16 @@ where
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a new filter object, based on our tracking policy.
|
||||||
|
fn filter(&self) -> Filter {
|
||||||
|
if self.config.policy == tracking::Policy::Track {
|
||||||
|
// TODO: Remove bits for blocked repos.
|
||||||
|
Filter::default()
|
||||||
|
} else {
|
||||||
|
self.filter.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Periodic tasks
|
// Periodic tasks
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -1242,14 +1272,6 @@ impl fmt::Display for DisconnectReason {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R, A, S, G> Iterator for Service<R, A, S, G> {
|
|
||||||
type Item = reactor::Io;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
self.reactor.next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Result of a project lookup.
|
/// Result of a project lookup.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Lookup {
|
pub struct Lookup {
|
||||||
|
|
|
||||||
|
|
@ -62,34 +62,30 @@ impl Config {
|
||||||
|
|
||||||
/// Check if a repository is tracked.
|
/// Check if a repository is tracked.
|
||||||
pub fn is_repo_tracked(&self, id: &Id) -> Result<bool, Error> {
|
pub fn is_repo_tracked(&self, id: &Id) -> Result<bool, Error> {
|
||||||
if self.default == Policy::Track {
|
self.repo_policy(id).map(|policy| policy == Policy::Track)
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
self.store.is_repo_tracked(id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a node is tracked.
|
/// Check if a node is tracked.
|
||||||
pub fn is_node_tracked(&self, id: &NodeId) -> Result<bool, Error> {
|
pub fn is_node_tracked(&self, id: &NodeId) -> Result<bool, Error> {
|
||||||
if self.default == Policy::Track {
|
self.node_policy(id).map(|policy| policy == Policy::Track)
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
self.store.is_node_tracked(id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a node's tracking information.
|
/// Get a node's tracking information.
|
||||||
pub fn node_entry(&self, id: &NodeId) -> Result<(Option<Alias>, Policy), Error> {
|
/// Returns the default policy if the node isn't found.
|
||||||
if let Some(result) = self.store.node_entry(id)? {
|
pub fn node_policy(&self, id: &NodeId) -> Result<Policy, Error> {
|
||||||
return Ok(result);
|
if let Some((_, policy)) = self.store.node_entry(id)? {
|
||||||
|
return Ok(policy);
|
||||||
}
|
}
|
||||||
Ok((None, self.default))
|
Ok(self.default)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a repository's tracking information.
|
/// Get a repository's tracking information.
|
||||||
pub fn repo_entry(&self, id: &Id) -> Result<(Scope, Policy), Error> {
|
/// Returns the default policy if the repo isn't found.
|
||||||
if let Some(result) = self.store.repo_entry(id)? {
|
pub fn repo_policy(&self, id: &Id) -> Result<Policy, Error> {
|
||||||
return Ok(result);
|
if let Some((_, policy)) = self.store.repo_entry(id)? {
|
||||||
|
return Ok(policy);
|
||||||
}
|
}
|
||||||
Ok((Scope::All, self.default))
|
Ok(self.default)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(clippy::type_complexity)]
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::{fmt, io};
|
use std::{fmt, io};
|
||||||
|
|
@ -247,35 +248,37 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get node tracking entries.
|
/// Get node tracking entries.
|
||||||
pub fn node_entries(&self) -> Result<Box<dyn Iterator<Item = (NodeId, Alias)>>, Error> {
|
pub fn node_entries(&self) -> Result<Box<dyn Iterator<Item = (NodeId, Alias, Policy)>>, Error> {
|
||||||
let mut stmt = self
|
let mut stmt = self
|
||||||
.db
|
.db
|
||||||
.prepare("SELECT id, alias FROM `node-policies`")?
|
.prepare("SELECT id, alias, policy FROM `node-policies`")?
|
||||||
.into_iter();
|
.into_iter();
|
||||||
let mut entries = Vec::new();
|
let mut entries = Vec::new();
|
||||||
|
|
||||||
while let Some(Ok(row)) = stmt.next() {
|
while let Some(Ok(row)) = stmt.next() {
|
||||||
let id = row.read("id");
|
let id = row.read("id");
|
||||||
let alias = row.read::<&str, _>("alias");
|
let alias = row.read::<&str, _>("alias");
|
||||||
|
let policy = row.read::<Policy, _>("policy");
|
||||||
|
|
||||||
entries.push((id, alias.to_owned()));
|
entries.push((id, alias.to_owned(), policy));
|
||||||
}
|
}
|
||||||
Ok(Box::new(entries.into_iter()))
|
Ok(Box::new(entries.into_iter()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get repository tracking entries.
|
/// Get repository tracking entries.
|
||||||
pub fn repo_entries(&self) -> Result<Box<dyn Iterator<Item = (Id, Scope)>>, Error> {
|
pub fn repo_entries(&self) -> Result<Box<dyn Iterator<Item = (Id, Scope, Policy)>>, Error> {
|
||||||
let mut stmt = self
|
let mut stmt = self
|
||||||
.db
|
.db
|
||||||
.prepare("SELECT id, scope FROM `repo-policies`")?
|
.prepare("SELECT id, scope, policy FROM `repo-policies`")?
|
||||||
.into_iter();
|
.into_iter();
|
||||||
let mut entries = Vec::new();
|
let mut entries = Vec::new();
|
||||||
|
|
||||||
while let Some(Ok(row)) = stmt.next() {
|
while let Some(Ok(row)) = stmt.next() {
|
||||||
let id = row.read("id");
|
let id = row.read("id");
|
||||||
let scope = row.read("scope");
|
let scope = row.read("scope");
|
||||||
|
let policy = row.read::<Policy, _>("policy");
|
||||||
|
|
||||||
entries.push((id, scope));
|
entries.push((id, scope, policy));
|
||||||
}
|
}
|
||||||
Ok(Box::new(entries.into_iter()))
|
Ok(Box::new(entries.into_iter()))
|
||||||
}
|
}
|
||||||
|
|
@ -321,9 +324,9 @@ mod test {
|
||||||
assert!(db.track_node(id, None).unwrap());
|
assert!(db.track_node(id, None).unwrap());
|
||||||
}
|
}
|
||||||
let mut entries = db.node_entries().unwrap();
|
let mut entries = db.node_entries().unwrap();
|
||||||
assert_matches!(entries.next(), Some((id, _)) if id == ids[0]);
|
assert_matches!(entries.next(), Some((id, _, _)) if id == ids[0]);
|
||||||
assert_matches!(entries.next(), Some((id, _)) if id == ids[1]);
|
assert_matches!(entries.next(), Some((id, _, _)) if id == ids[1]);
|
||||||
assert_matches!(entries.next(), Some((id, _)) if id == ids[2]);
|
assert_matches!(entries.next(), Some((id, _, _)) if id == ids[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -335,9 +338,9 @@ mod test {
|
||||||
assert!(db.track_repo(id, Scope::All).unwrap());
|
assert!(db.track_repo(id, Scope::All).unwrap());
|
||||||
}
|
}
|
||||||
let mut entries = db.repo_entries().unwrap();
|
let mut entries = db.repo_entries().unwrap();
|
||||||
assert_matches!(entries.next(), Some((id, _)) if id == ids[0]);
|
assert_matches!(entries.next(), Some((id, _, _)) if id == ids[0]);
|
||||||
assert_matches!(entries.next(), Some((id, _)) if id == ids[1]);
|
assert_matches!(entries.next(), Some((id, _, _)) if id == ids[1]);
|
||||||
assert_matches!(entries.next(), Some((id, _)) if id == ids[2]);
|
assert_matches!(entries.next(), Some((id, _, _)) if id == ids[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,7 @@ impl<S: WriteStorage + 'static, G: Signer> Simulation<S, G> {
|
||||||
for peer in nodes.values_mut() {
|
for peer in nodes.values_mut() {
|
||||||
let id = peer.id();
|
let id = peer.id();
|
||||||
|
|
||||||
for o in peer.by_ref() {
|
while let Some(o) = peer.next() {
|
||||||
self.schedule(&id, o);
|
self.schedule(&id, o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -417,7 +417,7 @@ impl<S: WriteStorage + 'static, G: Signer> Simulation<S, G> {
|
||||||
p.fetched(f, result);
|
p.fetched(f, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for o in p.by_ref() {
|
while let Some(o) = p.next() {
|
||||||
self.schedule(&node, o);
|
self.schedule(&node, o);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue