Cleanup and add syncing of resources

This commit is contained in:
onyinyang 2023-09-13 12:08:48 -04:00
parent d4c54e969c
commit be0d026fe8
No known key found for this signature in database
GPG Key ID: 156A6435430C2036
5 changed files with 89 additions and 74 deletions

View File

@ -25,6 +25,19 @@ pub struct LoxServerContext {
}
impl LoxServerContext {
pub fn bridgetable_is_empty(&self) -> bool {
let mut ba_obj = self.ba.lock().unwrap();
ba_obj.is_empty()
}
// Populate an empty bridgetable for the first time
/* pub fn populate_bridgetable(&self, bridgelines: Vec<BridgeLine>, percent_spares: Option<usize>) {
if Some(percent_spares) {
let partition: usize = bridgelines.len()*percent_spares/100;
}
} */
pub fn append_extra_bridges(&self, bridge: BridgeLine) {
let mut extra_bridges = self.extra_bridges.lock().unwrap();
extra_bridges.push(bridge);

View File

@ -1,7 +1,5 @@
use chrono::Utc;
use clap::Parser;
use futures::future;
use futures::StreamExt;
use hyper::{
server::conn::AddrStream,
service::{make_service_fn, service_fn},
@ -9,7 +7,7 @@ use hyper::{
};
use lox_library::bridge_table::{BridgeLine, MAX_BRIDGES_PER_BUCKET};
use rdsys_backend::{proto::Resource, proto::ResourceDiff, request_resources, start_stream};
use rdsys_backend::{proto::Resource, request_resources};
use serde::Deserialize;
use std::{
@ -22,7 +20,7 @@ mod lox_context;
mod request_handler;
use request_handler::handle;
mod resource_parser;
use resource_parser::parse_resource;
use resource_parser::parse_resources;
use tokio::{
signal, spawn,
@ -171,51 +169,61 @@ async fn context_manager(
Rdsys { resources } => {
let mut count = 0;
let mut bucket = [BridgeLine::default(); MAX_BRIDGES_PER_BUCKET];
for resource in resources {
let bridgeline = parse_resource(resource);
println!("What is the bridgeline: {:?}", bridgeline);
if context.to_be_replaced_bridges.lock().unwrap().len() > 0 {
println!("BridgeLine to be replaced: {:?}", bridgeline);
let res = context.replace_with_new(bridgeline);
if res == lox_library::ReplaceSuccess::NotFound {
println!(
"BridgeLine not found in bridge_table, already updated {:?}",
bridgeline
);
} else if res == lox_library::ReplaceSuccess::Replaced {
println!("BridgeLine successfully replaced: {:?}", bridgeline);
if context.bridgetable_is_empty() {
// otherwise, for each resource, check if the resource fingerprint is failing tests, if it is check for how long
// check if the resource is already in the Lox bridgetable
// if it is, it's probably fine to remove or replace the existing resource with the incoming one
// to account for changes unless we want to track the number of changes on the lox side?
// that should be sufficient to keep it in sync
let bridgelines = parse_resources(resources);
for bridgeline in bridgelines {
//context.populate_bridgetable(bridgelines. None);
println!("What is the bridgeline: {:?}", bridgeline);
if context.to_be_replaced_bridges.lock().unwrap().len() > 0 {
println!("BridgeLine to be replaced: {:?}", bridgeline);
let res = context.replace_with_new(bridgeline);
if res == lox_library::ReplaceSuccess::NotFound {
println!(
"BridgeLine not found in bridge_table, already updated {:?}",
bridgeline
);
} else if res == lox_library::ReplaceSuccess::Replaced {
println!("BridgeLine successfully replaced: {:?}", bridgeline);
} else {
assert!(
res == lox_library::ReplaceSuccess::NotReplaced,
"ReplaceSuccess incorrectly set somehow"
);
// Add the bridge to the list of to_be_replaced bridges in the Lox context and try
// again to replace at the next update (nothing changes in the Lox Authority)
println!(
"'Gone' BridgeLine NOT replaced, saved for next update! : {:?}",
bridgeline
);
context.new_to_be_replaced_bridge(bridgeline);
}
} else if count < MAX_BRIDGES_PER_BUCKET {
bucket[count] = bridgeline;
count += 1;
} else {
assert!(
res == lox_library::ReplaceSuccess::NotReplaced,
"ReplaceSuccess incorrectly set somehow"
);
// Add the bridge to the list of to_be_replaced bridges in the Lox context and try
// again to replace at the next update (nothing changes in the Lox Authority)
println!(
"'Gone' BridgeLine NOT replaced, saved for next update! : {:?}",
bridgeline
);
context.new_to_be_replaced_bridge(bridgeline);
// TODO: Decide the circumstances under which a bridge is allocated to an open_inv or spare bucket,
// eventually also do some more fancy grouping of new resources, i.e., by type or region
context.add_openinv_bucket(bucket);
count = 0;
bucket = [BridgeLine::default(); MAX_BRIDGES_PER_BUCKET];
}
} else if count < MAX_BRIDGES_PER_BUCKET {
bucket[count] = bridgeline;
count += 1;
} else {
// TODO: Decide the circumstances under which a bridge is allocated to an open_inv or spare bucket,
// eventually also do some more fancy grouping of new resources, i.e., by type or region
context.add_openinv_bucket(bucket);
count = 0;
bucket = [BridgeLine::default(); MAX_BRIDGES_PER_BUCKET];
}
}
// Handle the extra buckets that were not allocated already
if count != 0 {
for val in 0..count {
if context.extra_bridges.lock().unwrap().len() < (MAX_BRIDGES_PER_BUCKET) {
context.append_extra_bridges(bucket[val]);
} else {
bucket = context.remove_extra_bridges();
context.add_spare_bucket(bucket);
// Handle the extra buckets that were not allocated already
if count != 0 {
for val in 0..count {
if context.extra_bridges.lock().unwrap().len()
< (MAX_BRIDGES_PER_BUCKET)
{
context.append_extra_bridges(bucket[val]);
} else {
bucket = context.remove_extra_bridges();
context.add_spare_bucket(bucket);
}
}
}
}

View File

@ -1,13 +1,15 @@
use lox_library::bridge_table::{BridgeLine, BRIDGE_BYTES};
use rdsys_backend::proto::Resource;
pub fn parse_resource(resource: Resource) -> BridgeLine {
let mut ip_bytes: [u8; 16] = [0; 16];
ip_bytes[..resource.address.len()].copy_from_slice(resource.address.as_bytes());
let resource_uid = resource
.get_uid()
.expect("Unable to get Fingerprint UID of resource");
let infostr: String = format!(
pub fn parse_resources(resources: Vec<Resource>) -> Vec<BridgeLine> {
let mut bridgelines: Vec<BridgeLine> = Vec::new();
for resource in resources {
let mut ip_bytes: [u8; 16] = [0; 16];
ip_bytes[..resource.address.len()].copy_from_slice(resource.address.as_bytes());
let resource_uid = resource
.get_uid()
.expect("Unable to get Fingerprint UID of resource");
let infostr: String = format!(
"type={} blocked_in={:?} protocol={} fingerprint={:?} or_addresses={:?} distribution={} flags={:?} params={:?}",
resource.r#type,
resource.blocked_in,
@ -18,13 +20,15 @@ pub fn parse_resource(resource: Resource) -> BridgeLine {
resource.flags,
resource.params,
);
let mut info_bytes: [u8; BRIDGE_BYTES - 26] = [0; BRIDGE_BYTES - 26];
let mut info_bytes: [u8; BRIDGE_BYTES - 26] = [0; BRIDGE_BYTES - 26];
info_bytes[..infostr.len()].copy_from_slice(infostr.as_bytes());
BridgeLine {
addr: ip_bytes,
port: resource.port,
uid_fingerprint: resource_uid,
info: info_bytes,
info_bytes[..infostr.len()].copy_from_slice(infostr.as_bytes());
bridgelines.push(BridgeLine {
addr: ip_bytes,
port: resource.port,
uid_fingerprint: resource_uid,
info: info_bytes,
})
}
bridgelines
}

View File

@ -330,6 +330,10 @@ impl BridgeAuth {
}
}
pub fn is_empty(&mut self) -> bool {
self.bridge_table.buckets.is_empty()
}
/// Insert a set of open invitation bridges.
///
/// Each of the bridges will be given its own open invitation
@ -378,7 +382,6 @@ impl BridgeAuth {
// TODO Ensure synchronization of Lox bridge_table with rdsys
pub fn sync_table(&mut self) {
// Create a hashtable (?) of bridges in the lox distributor from new resources
// accept the hashtable and recreate the bridge table from the hash table here
// using existing reachable bridges, other table checks and placements from existing bridge table

View File

@ -40,17 +40,6 @@ impl From<io::Error> for Error {
}
}
pub struct StaticResourceRequest {}
impl StaticResourceRequest {
pub fn new(rx: mpsc::Receiver<Bytes>) -> StaticResourceRequest {
StaticResourceRequest {
}
}
}
/// An iterable wrapper of ResourceDiff items for the streamed chunks of Bytes
/// received from the connection to the rdsys backend
pub struct ResourceStream {
@ -295,7 +284,6 @@ pub async fn request_resources( api_endpoint: String,
.body(json)
.send()
.await.unwrap();
println!("Success? {:?}", response);
match response.status() {
reqwest::StatusCode::OK => {
fetched_resources = match dbg!(response.json::<Vec<proto::Resource>>().await) {
@ -307,6 +295,5 @@ pub async fn request_resources( api_endpoint: String,
fetched_resources = Err(Error::String(other))
}
};
println!("Resources: {:?}", fetched_resources);
fetched_resources
}