latest pushes
This commit is contained in:
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
### Node Management
|
### Node Management
|
||||||
- Discovery
|
- Discovery
|
||||||
- Automatic peer finding
|
- Automatic node finding
|
||||||
- Bootstrap nodes
|
- Bootstrap nodes
|
||||||
- Node registration
|
- Node registration
|
||||||
- Network topology
|
- Network topology
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
- Connection monitoring
|
- Connection monitoring
|
||||||
|
|
||||||
- Data Synchronization
|
- Data Synchronization
|
||||||
- Peer sync protocols
|
- Node sync protocols
|
||||||
- Data chunk transfer
|
- Data chunk transfer
|
||||||
- State reconciliation
|
- State reconciliation
|
||||||
- Conflict resolution
|
- Conflict resolution
|
||||||
|
@@ -29,7 +29,7 @@ mod persistence;
|
|||||||
pub use crate::config::config::Config;
|
pub use crate::config::config::Config;
|
||||||
pub use crate::error::error::BellandeMeshError;
|
pub use crate::error::error::BellandeMeshError;
|
||||||
pub use crate::mesh::mesh::BellandeMeshSync;
|
pub use crate::mesh::mesh::BellandeMeshSync;
|
||||||
use crate::mesh::mesh::NetworkStats;
|
pub use crate::mesh::mesh::NetworkStats;
|
||||||
pub use crate::metrics::metrics::MetricsManager;
|
pub use crate::metrics::metrics::MetricsManager;
|
||||||
pub use crate::node::node::{Node, NodeId, PublicKey};
|
pub use crate::node::node::{Node, NodeId, PublicKey};
|
||||||
pub use crate::persistence::persistence::PersistenceManager;
|
pub use crate::persistence::persistence::PersistenceManager;
|
||||||
|
279
src/mesh/mesh.rs
279
src/mesh/mesh.rs
@@ -30,11 +30,11 @@ use std::fs;
|
|||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::net::{SocketAddr, TcpStream};
|
use std::net::{SocketAddr, TcpStream};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
use tokio::net::{TcpListener as TokioTcpListener, UdpSocket as TokioUdpSocket};
|
use tokio::net::{TcpListener as TokioTcpListener, UdpSocket as TokioUdpSocket};
|
||||||
use tokio::signal;
|
use tokio::signal;
|
||||||
use tokio::sync::{mpsc, Mutex};
|
use tokio::sync::{mpsc, Mutex, RwLock};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
@@ -83,7 +83,7 @@ pub struct BellandeMeshSync {
|
|||||||
https_client: Client<hyper_rustls::HttpsConnector<hyper::client::HttpConnector>>,
|
https_client: Client<hyper_rustls::HttpsConnector<hyper::client::HttpConnector>>,
|
||||||
stats: Arc<RwLock<NetworkStats>>,
|
stats: Arc<RwLock<NetworkStats>>,
|
||||||
metrics: Arc<MetricsManager>,
|
metrics: Arc<MetricsManager>,
|
||||||
message_tx: mpsc::Sender<(Message, SocketAddr)>,
|
message_tx: Arc<Mutex<mpsc::Sender<(Message, SocketAddr)>>>,
|
||||||
message_rx: Arc<Mutex<mpsc::Receiver<(Message, SocketAddr)>>>,
|
message_rx: Arc<Mutex<mpsc::Receiver<(Message, SocketAddr)>>>,
|
||||||
cancel_token: CancellationToken,
|
cancel_token: CancellationToken,
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@ impl BellandeMeshSync {
|
|||||||
https_client,
|
https_client,
|
||||||
stats,
|
stats,
|
||||||
metrics,
|
metrics,
|
||||||
message_tx,
|
message_tx: Arc::new(Mutex::new(message_tx)),
|
||||||
message_rx: Arc::new(Mutex::new(message_rx)),
|
message_rx: Arc::new(Mutex::new(message_rx)),
|
||||||
cancel_token: CancellationToken::new(),
|
cancel_token: CancellationToken::new(),
|
||||||
})
|
})
|
||||||
@@ -169,7 +169,7 @@ impl BellandeMeshSync {
|
|||||||
https_client,
|
https_client,
|
||||||
stats,
|
stats,
|
||||||
metrics,
|
metrics,
|
||||||
message_tx,
|
message_tx: Arc::new(Mutex::new(message_tx)),
|
||||||
message_rx: Arc::new(Mutex::new(message_rx)),
|
message_rx: Arc::new(Mutex::new(message_rx)),
|
||||||
cancel_token: CancellationToken::new(),
|
cancel_token: CancellationToken::new(),
|
||||||
})
|
})
|
||||||
@@ -204,12 +204,10 @@ impl BellandeMeshSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start(&self) -> Result<(), BellandeMeshError> {
|
pub async fn start(&self) -> Result<(), BellandeMeshError> {
|
||||||
let mut running = self
|
{
|
||||||
.running
|
let mut running = self.running.write().await;
|
||||||
.write()
|
*running = true;
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
}
|
||||||
*running = true;
|
|
||||||
drop(running);
|
|
||||||
|
|
||||||
self.start_message_handler().await?;
|
self.start_message_handler().await?;
|
||||||
self.start_protocol_listeners().await?;
|
self.start_protocol_listeners().await?;
|
||||||
@@ -219,10 +217,7 @@ impl BellandeMeshSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn stop(&self) -> Result<(), BellandeMeshError> {
|
pub async fn stop(&self) -> Result<(), BellandeMeshError> {
|
||||||
let mut running = self
|
let mut running = self.running.write().await;
|
||||||
.running
|
|
||||||
.write()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
*running = false;
|
*running = false;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -230,8 +225,16 @@ impl BellandeMeshSync {
|
|||||||
pub async fn start_message_handler(&self) -> Result<(), BellandeMeshError> {
|
pub async fn start_message_handler(&self) -> Result<(), BellandeMeshError> {
|
||||||
let handler = self.clone();
|
let handler = self.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut rx = handler.message_rx.lock().await;
|
loop {
|
||||||
while let Some((message, addr)) = rx.recv().await {
|
let message = {
|
||||||
|
let mut rx = handler.message_rx.lock().await;
|
||||||
|
match rx.recv().await {
|
||||||
|
Some(msg) => msg,
|
||||||
|
None => break,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let (message, addr) = message;
|
||||||
if let Err(e) = handler.handle_message_internal(message, addr).await {
|
if let Err(e) = handler.handle_message_internal(message, addr).await {
|
||||||
eprintln!("Message handling error from {}: {}", addr, e);
|
eprintln!("Message handling error from {}: {}", addr, e);
|
||||||
}
|
}
|
||||||
@@ -254,18 +257,28 @@ impl BellandeMeshSync {
|
|||||||
.listen_address
|
.listen_address
|
||||||
.parse::<SocketAddr>()
|
.parse::<SocketAddr>()
|
||||||
.map_err(|e| BellandeMeshError::Custom(format!("Invalid address: {}", e)))?;
|
.map_err(|e| BellandeMeshError::Custom(format!("Invalid address: {}", e)))?;
|
||||||
|
|
||||||
let listener = TokioTcpListener::bind(addr).await?;
|
let listener = TokioTcpListener::bind(addr).await?;
|
||||||
let handler = self.clone();
|
let handler = self.clone();
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
while handler.is_running().unwrap_or(false) {
|
loop {
|
||||||
if let Ok((stream, addr)) = listener.accept().await {
|
match handler.is_running().await {
|
||||||
let handler = handler.clone();
|
Ok(true) => {
|
||||||
tokio::spawn(async move {
|
if let Ok((stream, addr)) = listener.accept().await {
|
||||||
if let Err(e) = handler.handle_tcp_connection(stream).await {
|
let handler = handler.clone();
|
||||||
eprintln!("TCP error from {}: {}", addr, e);
|
tokio::spawn(async move {
|
||||||
|
if let Err(e) = handler.handle_tcp_connection(stream).await {
|
||||||
|
eprintln!("TCP error from {}: {}", addr, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
Ok(false) => break,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error checking running state: {}", e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -371,7 +384,7 @@ impl BellandeMeshSync {
|
|||||||
let tls_acceptor = tokio_rustls::TlsAcceptor::from(tls_config);
|
let tls_acceptor = tokio_rustls::TlsAcceptor::from(tls_config);
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
while handler.is_running().unwrap_or(false) {
|
while handler.is_running().await.unwrap_or(false) {
|
||||||
if let Ok((stream, addr)) = listener.accept().await {
|
if let Ok((stream, addr)) = listener.accept().await {
|
||||||
let handler = handler.clone();
|
let handler = handler.clone();
|
||||||
let acceptor = tls_acceptor.clone();
|
let acceptor = tls_acceptor.clone();
|
||||||
@@ -492,10 +505,14 @@ impl BellandeMeshSync {
|
|||||||
let (mut reader, mut writer) = tokio::io::split(stream);
|
let (mut reader, mut writer) = tokio::io::split(stream);
|
||||||
let mut buf = [0u8; MAX_MESSAGE_SIZE];
|
let mut buf = [0u8; MAX_MESSAGE_SIZE];
|
||||||
|
|
||||||
while self.is_running()? {
|
loop {
|
||||||
|
if !self.is_running().await? {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
match self.read_async_message(&mut reader, &mut buf).await {
|
match self.read_async_message(&mut reader, &mut buf).await {
|
||||||
Ok(message) => {
|
Ok(message) => {
|
||||||
self.update_stats(|stats| stats.total_messages += 1);
|
self.update_stats(|stats| stats.total_messages += 1).await?;
|
||||||
if let Err(e) = self.write_async_message(&mut writer, &message).await {
|
if let Err(e) = self.write_async_message(&mut writer, &message).await {
|
||||||
eprintln!("Write error: {}", e);
|
eprintln!("Write error: {}", e);
|
||||||
break;
|
break;
|
||||||
@@ -694,19 +711,20 @@ impl BellandeMeshSync {
|
|||||||
vec![],
|
vec![],
|
||||||
);
|
);
|
||||||
|
|
||||||
let nodes = self
|
let target_addr = {
|
||||||
.nodes
|
let nodes = self.nodes.read().await;
|
||||||
.read()
|
if let Some(node) = nodes.iter().find(|n| n.address == src) {
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
let mut data = node.data.write().await;
|
||||||
if let Some(node) = nodes.iter().find(|n| n.address == src) {
|
data.insert(NodeId::from_bytes(&key), chunk);
|
||||||
let mut data = node
|
Some(node.address)
|
||||||
.data
|
} else {
|
||||||
.write()
|
None
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
}
|
||||||
data.insert(NodeId::from_bytes(&key), chunk);
|
};
|
||||||
|
|
||||||
// Replicate to closest nodes
|
if target_addr.is_some() {
|
||||||
let closest_nodes = self.find_closest_nodes(&NodeId::from_bytes(&key), 3).await;
|
let closest_nodes = self.find_closest_nodes(&NodeId::from_bytes(&key), 3).await;
|
||||||
|
|
||||||
for target_node in closest_nodes {
|
for target_node in closest_nodes {
|
||||||
let store_msg = Message::Store {
|
let store_msg = Message::Store {
|
||||||
key: key.clone(),
|
key: key.clone(),
|
||||||
@@ -714,6 +732,7 @@ impl BellandeMeshSync {
|
|||||||
sender: self.get_local_id().await?,
|
sender: self.get_local_id().await?,
|
||||||
token: rand::random(),
|
token: rand::random(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(e) = self.send_message(target_node.address, &store_msg).await {
|
if let Err(e) = self.send_message(target_node.address, &store_msg).await {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Failed to replicate store to {}: {}",
|
"Failed to replicate store to {}: {}",
|
||||||
@@ -747,26 +766,24 @@ impl BellandeMeshSync {
|
|||||||
src: SocketAddr,
|
src: SocketAddr,
|
||||||
) -> Result<(), BellandeMeshError> {
|
) -> Result<(), BellandeMeshError> {
|
||||||
let node_id = NodeId::from_bytes(&key);
|
let node_id = NodeId::from_bytes(&key);
|
||||||
let nodes = self
|
let nodes = self.nodes.read().await;
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
|
|
||||||
|
// If node.data is tokio::sync::RwLock
|
||||||
for node in nodes.iter() {
|
for node in nodes.iter() {
|
||||||
if let Ok(data) = node.data.read() {
|
let data = node.data.read().await;
|
||||||
if let Some(chunk) = data.get(&node_id) {
|
if let Some(chunk) = data.get(&node_id) {
|
||||||
let response = Message::Value {
|
let response = Message::Value {
|
||||||
key: key.clone(),
|
key: key.clone(),
|
||||||
value: chunk.content.clone(),
|
value: chunk.content.clone(),
|
||||||
sender: self.get_local_id().await?,
|
sender: self.get_local_id().await?,
|
||||||
token: rand::random(),
|
token: rand::random(),
|
||||||
};
|
};
|
||||||
return self.send_message(src, &response).await;
|
return self.send_message(src, &response).await;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not found, return closest nodes
|
// If not found, return closest nodes
|
||||||
|
drop(nodes);
|
||||||
let closest_nodes = self.find_closest_nodes(&node_id, 20).await;
|
let closest_nodes = self.find_closest_nodes(&node_id, 20).await;
|
||||||
let response = Message::Nodes {
|
let response = Message::Nodes {
|
||||||
nodes: closest_nodes,
|
nodes: closest_nodes,
|
||||||
@@ -806,15 +823,12 @@ impl BellandeMeshSync {
|
|||||||
vec![],
|
vec![],
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut nodes = self
|
let mut nodes = self.nodes.write().await;
|
||||||
.nodes
|
|
||||||
.write()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
if let Some(node) = nodes.first_mut() {
|
if let Some(node) = nodes.first_mut() {
|
||||||
if let Ok(mut data) = node.data.write() {
|
// If node.data is tokio::sync::RwLock
|
||||||
data.insert(NodeId::from_bytes(&key), chunk);
|
let mut data = node.data.write().await;
|
||||||
self.metrics.increment_sync_operations();
|
data.insert(NodeId::from_bytes(&key), chunk);
|
||||||
}
|
self.metrics.increment_sync_operations();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -823,10 +837,7 @@ impl BellandeMeshSync {
|
|||||||
where
|
where
|
||||||
F: FnOnce(&mut NetworkStats),
|
F: FnOnce(&mut NetworkStats),
|
||||||
{
|
{
|
||||||
let mut stats = self
|
let mut stats = self.stats.write().await;
|
||||||
.stats
|
|
||||||
.write()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
updater(&mut stats);
|
updater(&mut stats);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -862,10 +873,7 @@ impl BellandeMeshSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_node_last_seen(&self, addr: SocketAddr) -> Result<(), BellandeMeshError> {
|
pub async fn update_node_last_seen(&self, addr: SocketAddr) -> Result<(), BellandeMeshError> {
|
||||||
let mut nodes = self
|
let mut nodes = self.nodes.write().await;
|
||||||
.nodes
|
|
||||||
.write()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
if let Some(node) = nodes.iter_mut().find(|n| n.address == addr) {
|
if let Some(node) = nodes.iter_mut().find(|n| n.address == addr) {
|
||||||
node.update_last_seen();
|
node.update_last_seen();
|
||||||
}
|
}
|
||||||
@@ -900,13 +908,10 @@ impl BellandeMeshSync {
|
|||||||
let new_node = Node::new(id, addr, public_key);
|
let new_node = Node::new(id, addr, public_key);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut nodes = self
|
let mut nodes = self.nodes.write().await;
|
||||||
.nodes
|
|
||||||
.write()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
if !nodes.iter().any(|n| n.id == new_node.id) {
|
if !nodes.iter().any(|n| n.id == new_node.id) {
|
||||||
nodes.push(new_node.clone());
|
nodes.push(new_node.clone());
|
||||||
self.update_stats(|stats| stats.active_nodes += 1);
|
self.update_stats(|stats| stats.active_nodes += 1).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -915,10 +920,7 @@ impl BellandeMeshSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_data_sync(&self, chunks: Vec<DataChunk>) -> Result<(), BellandeMeshError> {
|
pub async fn handle_data_sync(&self, chunks: Vec<DataChunk>) -> Result<(), BellandeMeshError> {
|
||||||
let nodes = self
|
let nodes = self.nodes.read().await;
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
|
|
||||||
for chunk in chunks {
|
for chunk in chunks {
|
||||||
if let Some(node) = nodes.iter().find(|n| n.id == chunk.author) {
|
if let Some(node) = nodes.iter().find(|n| n.id == chunk.author) {
|
||||||
@@ -934,10 +936,7 @@ impl BellandeMeshSync {
|
|||||||
ids: &[NodeId],
|
ids: &[NodeId],
|
||||||
src: SocketAddr,
|
src: SocketAddr,
|
||||||
) -> Result<(), BellandeMeshError> {
|
) -> Result<(), BellandeMeshError> {
|
||||||
let nodes = self
|
let nodes = self.nodes.read().await;
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
let mut chunks = Vec::new();
|
let mut chunks = Vec::new();
|
||||||
|
|
||||||
for node in nodes.iter() {
|
for node in nodes.iter() {
|
||||||
@@ -968,10 +967,7 @@ impl BellandeMeshSync {
|
|||||||
sender: NodeId,
|
sender: NodeId,
|
||||||
src: SocketAddr,
|
src: SocketAddr,
|
||||||
) -> Result<(), BellandeMeshError> {
|
) -> Result<(), BellandeMeshError> {
|
||||||
let mut nodes = self
|
let mut nodes = self.nodes.write().await;
|
||||||
.nodes
|
|
||||||
.write()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
if let Some(node) = nodes.iter_mut().find(|n| n.id == sender) {
|
if let Some(node) = nodes.iter_mut().find(|n| n.id == sender) {
|
||||||
node.update_last_seen();
|
node.update_last_seen();
|
||||||
}
|
}
|
||||||
@@ -1013,17 +1009,14 @@ impl BellandeMeshSync {
|
|||||||
|
|
||||||
pub async fn sync_with_peers(&self) -> Result<(), BellandeMeshError> {
|
pub async fn sync_with_peers(&self) -> Result<(), BellandeMeshError> {
|
||||||
let nodes = {
|
let nodes = {
|
||||||
let nodes_guard = self
|
let nodes_guard = self.nodes.read().await;
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
nodes_guard.to_vec()
|
nodes_guard.to_vec()
|
||||||
};
|
};
|
||||||
|
|
||||||
for node in nodes {
|
for node in nodes {
|
||||||
if let Ok(mut stream) = TcpStream::connect(node.address) {
|
if let Ok(mut stream) = TcpStream::connect(node.address) {
|
||||||
let chunks = {
|
let chunks = {
|
||||||
let data = node.data.read().map_err(|_| BellandeMeshError::LockError)?;
|
let data = node.data.read().await; // Assuming node.data is also tokio::sync::RwLock
|
||||||
data.keys().cloned().collect::<Vec<_>>()
|
data.keys().cloned().collect::<Vec<_>>()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1043,7 +1036,8 @@ impl BellandeMeshSync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_stats(|stats| stats.last_sync = SystemTime::now());
|
self.update_stats(|stats| stats.last_sync = SystemTime::now())
|
||||||
|
.await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1057,7 +1051,7 @@ impl BellandeMeshSync {
|
|||||||
|
|
||||||
// Find the target node
|
// Find the target node
|
||||||
if let Some(node) = nodes.iter().find(|n| n.id == node_id) {
|
if let Some(node) = nodes.iter().find(|n| n.id == node_id) {
|
||||||
// Get write lock on node's data
|
// Get write lock on node's data (using tokio::sync::RwLock)
|
||||||
let mut data = node.data.write().await;
|
let mut data = node.data.write().await;
|
||||||
|
|
||||||
// Insert all chunks
|
// Insert all chunks
|
||||||
@@ -1088,7 +1082,12 @@ impl BellandeMeshSync {
|
|||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut interval = tokio::time::interval(Duration::from_secs(interval));
|
let mut interval = tokio::time::interval(Duration::from_secs(interval));
|
||||||
while let Ok(true) = running.read().map(|guard| *guard) {
|
loop {
|
||||||
|
let is_running = *running.read().await;
|
||||||
|
if !is_running {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
interval.tick().await;
|
interval.tick().await;
|
||||||
metrics.increment_sync_operations();
|
metrics.increment_sync_operations();
|
||||||
}
|
}
|
||||||
@@ -1098,10 +1097,7 @@ impl BellandeMeshSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_max_connections(&self, max_conn: usize) -> Result<(), BellandeMeshError> {
|
pub async fn set_max_connections(&self, max_conn: usize) -> Result<(), BellandeMeshError> {
|
||||||
let mut nodes = self
|
let mut nodes = self.nodes.write().await;
|
||||||
.nodes
|
|
||||||
.write()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
if nodes.len() > max_conn {
|
if nodes.len() > max_conn {
|
||||||
nodes.sort_by(|a, b| b.last_seen.cmp(&a.last_seen));
|
nodes.sort_by(|a, b| b.last_seen.cmp(&a.last_seen));
|
||||||
nodes.truncate(max_conn);
|
nodes.truncate(max_conn);
|
||||||
@@ -1110,10 +1106,7 @@ impl BellandeMeshSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn broadcast_data(&self, data: Vec<u8>) -> Result<(), BellandeMeshError> {
|
pub async fn broadcast_data(&self, data: Vec<u8>) -> Result<(), BellandeMeshError> {
|
||||||
let nodes = self
|
let nodes = self.nodes.read().await;
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
let local_id = self.get_local_id().await?;
|
let local_id = self.get_local_id().await?;
|
||||||
|
|
||||||
let message = Message::Store {
|
let message = Message::Store {
|
||||||
@@ -1133,14 +1126,8 @@ impl BellandeMeshSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_network_stats(&self) -> Result<NetworkStats, BellandeMeshError> {
|
pub async fn get_network_stats(&self) -> Result<NetworkStats, BellandeMeshError> {
|
||||||
let stats = self
|
let stats = self.stats.read().await;
|
||||||
.stats
|
let nodes = self.nodes.read().await;
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
let nodes = self
|
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
|
|
||||||
Ok(NetworkStats {
|
Ok(NetworkStats {
|
||||||
tcp_connections: stats.tcp_connections,
|
tcp_connections: stats.tcp_connections,
|
||||||
@@ -1159,10 +1146,7 @@ impl BellandeMeshSync {
|
|||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<(), BellandeMeshError> {
|
) -> Result<(), BellandeMeshError> {
|
||||||
let nodes = self
|
let nodes = self.nodes.read().await;
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
let node = nodes
|
let node = nodes
|
||||||
.iter()
|
.iter()
|
||||||
.find(|n| n.id == node_id)
|
.find(|n| n.id == node_id)
|
||||||
@@ -1181,10 +1165,7 @@ impl BellandeMeshSync {
|
|||||||
|
|
||||||
pub async fn cleanup_dead_nodes(&self) -> Result<(), BellandeMeshError> {
|
pub async fn cleanup_dead_nodes(&self) -> Result<(), BellandeMeshError> {
|
||||||
let timeout = Duration::from_secs(self.config.node_timeout);
|
let timeout = Duration::from_secs(self.config.node_timeout);
|
||||||
let mut nodes = self
|
let mut nodes = self.nodes.write().await;
|
||||||
.nodes
|
|
||||||
.write()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
|
|
||||||
let initial_count = nodes.len();
|
let initial_count = nodes.len();
|
||||||
nodes.retain(|node| {
|
nodes.retain(|node| {
|
||||||
@@ -1197,17 +1178,15 @@ impl BellandeMeshSync {
|
|||||||
|
|
||||||
let removed = initial_count - nodes.len();
|
let removed = initial_count - nodes.len();
|
||||||
if removed > 0 {
|
if removed > 0 {
|
||||||
self.update_stats(|stats| stats.active_nodes -= removed);
|
self.update_stats(|stats| stats.active_nodes -= removed)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_ping_to_all_nodes(&self) -> Result<(), BellandeMeshError> {
|
pub async fn send_ping_to_all_nodes(&self) -> Result<(), BellandeMeshError> {
|
||||||
let nodes = self
|
let nodes = self.nodes.read().await;
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
let local_id = self.get_local_id().await?;
|
let local_id = self.get_local_id().await?;
|
||||||
let token = rand::random::<u64>();
|
let token = rand::random::<u64>();
|
||||||
let ping = Message::Ping {
|
let ping = Message::Ping {
|
||||||
@@ -1241,34 +1220,26 @@ impl BellandeMeshSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_status(&self) -> String {
|
pub async fn get_status(&self) -> String {
|
||||||
let stats = self
|
let stats = self.stats.read().await.clone();
|
||||||
.stats
|
|
||||||
.read()
|
|
||||||
.map(|guard| guard.clone())
|
|
||||||
.unwrap_or_else(|_| NetworkStats::default());
|
|
||||||
|
|
||||||
serde_json::to_string_pretty(&stats).unwrap_or_else(|_| "Error getting status".to_string())
|
serde_json::to_string_pretty(&stats).unwrap_or_else(|_| "Error getting status".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn is_running(&self) -> Result<bool, BellandeMeshError> {
|
pub async fn is_running(&self) -> Result<bool, BellandeMeshError> {
|
||||||
self.running
|
Ok(*self.running.read().await)
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)
|
|
||||||
.map(|guard| *guard)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_local_id(&self) -> Result<NodeId, BellandeMeshError> {
|
pub async fn get_local_id(&self) -> Result<NodeId, BellandeMeshError> {
|
||||||
self.nodes
|
Ok(self
|
||||||
|
.nodes
|
||||||
.read()
|
.read()
|
||||||
.map_err(|_| BellandeMeshError::LockError)
|
.await
|
||||||
.map(|nodes| nodes.first().map(|n| n.id).unwrap_or_else(|| NodeId::new()))
|
.first()
|
||||||
|
.map(|n| n.id)
|
||||||
|
.unwrap_or_else(|| NodeId::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn broadcast_new_node(&self, new_node: &Node) -> Result<(), BellandeMeshError> {
|
pub async fn broadcast_new_node(&self, new_node: &Node) -> Result<(), BellandeMeshError> {
|
||||||
let nodes = self
|
let nodes = self.nodes.read().await;
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
let message = Message::JoinResponse {
|
let message = Message::JoinResponse {
|
||||||
accepted: true,
|
accepted: true,
|
||||||
nodes: vec![new_node.clone()],
|
nodes: vec![new_node.clone()],
|
||||||
@@ -1281,48 +1252,28 @@ impl BellandeMeshSync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn broadcast_message(&self, message: Message) -> Result<(), BellandeMeshError> {
|
pub async fn broadcast_message(&self, message: Message) -> Result<(), BellandeMeshError> {
|
||||||
let nodes = self
|
let nodes = self.nodes.read().await;
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
|
|
||||||
for node in nodes.iter() {
|
for node in nodes.iter() {
|
||||||
if let Err(e) = self.send_message(node.address, &message).await {
|
if let Err(e) = self.send_message(node.address, &message).await {
|
||||||
eprintln!("Failed to broadcast message to {}: {}", node.address, e);
|
eprintln!("Failed to broadcast message to {}: {}", node.address, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_node_count(&self) -> Result<usize, BellandeMeshError> {
|
pub async fn get_node_count(&self) -> Result<usize, BellandeMeshError> {
|
||||||
Ok(self
|
Ok(self.nodes.read().await.len())
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?
|
|
||||||
.len())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_node_list(&self) -> Result<Vec<NodeId>, BellandeMeshError> {
|
pub async fn get_node_list(&self) -> Result<Vec<NodeId>, BellandeMeshError> {
|
||||||
Ok(self
|
Ok(self.nodes.read().await.iter().map(|node| node.id).collect())
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?
|
|
||||||
.iter()
|
|
||||||
.map(|node| node.id)
|
|
||||||
.collect())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn is_node_connected(&self, node_id: &NodeId) -> Result<bool, BellandeMeshError> {
|
pub async fn is_node_connected(&self, node_id: &NodeId) -> Result<bool, BellandeMeshError> {
|
||||||
let nodes = self
|
let nodes = self.nodes.read().await;
|
||||||
.nodes
|
|
||||||
.read()
|
|
||||||
.map_err(|_| BellandeMeshError::LockError)?;
|
|
||||||
Ok(nodes.iter().any(|node| &node.id == node_id))
|
Ok(nodes.iter().any(|node| &node.id == node_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1338,7 +1289,7 @@ impl Clone for BellandeMeshSync {
|
|||||||
https_client: self.https_client.clone(),
|
https_client: self.https_client.clone(),
|
||||||
stats: Arc::clone(&self.stats),
|
stats: Arc::clone(&self.stats),
|
||||||
metrics: Arc::clone(&self.metrics),
|
metrics: Arc::clone(&self.metrics),
|
||||||
message_tx: self.message_tx.clone(),
|
message_tx: Arc::clone(&self.message_tx),
|
||||||
message_rx: Arc::clone(&self.message_rx),
|
message_rx: Arc::clone(&self.message_rx),
|
||||||
cancel_token: CancellationToken::new(),
|
cancel_token: CancellationToken::new(),
|
||||||
}
|
}
|
||||||
|
@@ -19,8 +19,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize, Deserialize, PartialOrd, Ord)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize, Deserialize, PartialOrd, Ord)]
|
||||||
pub struct NodeId([u8; 32]);
|
pub struct NodeId([u8; 32]);
|
||||||
@@ -167,32 +168,34 @@ impl Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_data_chunk(&self, chunk: DataChunk) -> bool {
|
pub fn add_data_chunk(&self, chunk: DataChunk) -> bool {
|
||||||
match self.data.write() {
|
let data = self.data.clone();
|
||||||
Ok(mut data) => {
|
tokio::runtime::Handle::current().block_on(async move {
|
||||||
data.insert(chunk.id, chunk);
|
let mut guard = data.write().await;
|
||||||
true
|
guard.insert(chunk.id, chunk);
|
||||||
}
|
true
|
||||||
Err(_) => false,
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_data_chunk(&self, id: &NodeId) -> Option<DataChunk> {
|
pub fn get_data_chunk(&self, id: &NodeId) -> Option<DataChunk> {
|
||||||
self.data.read().ok()?.get(id).cloned()
|
let data = self.data.clone();
|
||||||
|
tokio::runtime::Handle::current().block_on(async move {
|
||||||
|
let guard = data.read().await;
|
||||||
|
guard.get(id).cloned()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_old_data(&self, max_age: Duration) -> bool {
|
pub fn remove_old_data(&self, max_age: Duration) -> bool {
|
||||||
match self.data.write() {
|
let data = self.data.clone();
|
||||||
Ok(mut data) => {
|
tokio::runtime::Handle::current().block_on(async move {
|
||||||
let now = SystemTime::now();
|
let mut guard = data.write().await;
|
||||||
data.retain(|_, chunk| {
|
let now = SystemTime::now();
|
||||||
now.duration_since(chunk.last_modified)
|
guard.retain(|_, chunk| {
|
||||||
.map(|age| age <= max_age)
|
now.duration_since(chunk.last_modified)
|
||||||
.unwrap_or(false)
|
.map(|age| age <= max_age)
|
||||||
});
|
.unwrap_or(false)
|
||||||
true
|
});
|
||||||
}
|
true
|
||||||
Err(_) => false,
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_alive(&self, timeout: Duration) -> bool {
|
pub fn is_alive(&self, timeout: Duration) -> bool {
|
||||||
|
@@ -22,8 +22,9 @@ use std::fs::{File, OpenOptions};
|
|||||||
use std::io::{BufReader, BufWriter};
|
use std::io::{BufReader, BufWriter};
|
||||||
use std::os::unix::fs::MetadataExt;
|
use std::os::unix::fs::MetadataExt;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct SerializableNode {
|
struct SerializableNode {
|
||||||
|
Reference in New Issue
Block a user