use alloc::{vec::Vec, collections::{BTreeMap, VecDeque, BTreeSet}, string::String};
use core::mem;
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
use crate::{Result, SwarmError, AgentId, Message, MessageType, MessagePayload};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ChannelConfig {
pub max_messages: usize,
pub persistent: bool,
pub compression: bool,
pub timeout: u64,
}
impl Default for ChannelConfig {
fn default() -> Self {
Self {
max_messages: 1000,
persistent: false,
compression: false,
timeout: 10000,
}
}
}
#[derive(Debug)]
pub struct MessageChannel {
pub id: u64,
pub sender: AgentId,
pub receiver: AgentId,
queue: VecDeque<Message>,
config: ChannelConfig,
stats: ChannelStats,
}
impl MessageChannel {
pub fn new(sender: AgentId, receiver: AgentId, config: ChannelConfig) -> Self {
static mut COUNTER: u64 = 0;
let id = unsafe {
COUNTER += 1;
COUNTER
};
Self {
id,
sender,
receiver,
queue: VecDeque::with_capacity(config.max_messages),
config,
stats: ChannelStats::default(),
}
}
pub fn send(&mut self, message: Message) -> Result<()> {
if message.from != self.sender {
return Err(SwarmError::channel("Invalid sender for channel"));
}
if self.queue.len() >= self.config.max_messages {
return Err(SwarmError::channel("Channel queue full"));
}
self.queue.push_back(message);
self.stats.messages_sent += 1;
Ok(())
}
pub fn receive(&mut self) -> Result<Option<Message>> {
if let Some(message) = self.queue.pop_front() {
self.stats.messages_received += 1;
Ok(Some(message))
} else {
Ok(None)
}
}
pub fn peek(&self) -> Option<&Message> {
self.queue.front()
}
pub fn pending_count(&self) -> usize {
self.queue.len()
}
pub fn is_empty(&self) -> bool {
self.queue.is_empty()
}
pub fn clear(&mut self) {
self.queue.clear();
self.stats.messages_dropped += self.stats.messages_sent - self.stats.messages_received;
}
pub fn stats(&self) -> &ChannelStats {
&self.stats
}
}
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ChannelStats {
pub messages_sent: u64,
pub messages_received: u64,
pub messages_dropped: u64,
pub average_message_size: f32,
pub utilization: f32,
}
pub struct CommunicationHub {
channels: BTreeMap<(AgentId, AgentId), MessageChannel>,
broadcast_channels: BTreeMap<String, BroadcastChannel>,
global_stats: GlobalChannelStats,
config: ChannelConfig,
}
impl CommunicationHub {
pub fn new(config: ChannelConfig) -> Self {
Self {
channels: BTreeMap::new(),
broadcast_channels: BTreeMap::new(),
global_stats: GlobalChannelStats::default(),
config,
}
}
pub fn create_channel(&mut self, sender: AgentId, receiver: AgentId) -> Result<()> {
let key = (sender, receiver);
if self.channels.contains_key(&key) {
return Err(SwarmError::channel("Channel already exists"));
}
let channel = MessageChannel::new(sender, receiver, self.config.clone());
self.channels.insert(key, channel);
Ok(())
}
pub fn remove_channel(&mut self, sender: AgentId, receiver: AgentId) -> Result<()> {
let key = (sender, receiver);
if self.channels.remove(&key).is_none() {
return Err(SwarmError::channel("Channel not found"));
}
Ok(())
}
pub fn send_message(&mut self, message: Message) -> Result<()> {
let key = (message.from, message.to);
if let Some(channel) = self.channels.get_mut(&key) {
channel.send(message)?;
self.global_stats.total_messages_sent += 1;
return Ok(());
}
self.create_channel(message.from, message.to)?;
let channel = self.channels.get_mut(&key).unwrap();
channel.send(message)?;
self.global_stats.total_messages_sent += 1;
Ok(())
}
pub fn receive_messages(&mut self, agent_id: AgentId) -> Vec<Message> {
let mut messages = Vec::new();
for ((_, receiver), channel) in self.channels.iter_mut() {
if *receiver == agent_id {
while let Ok(Some(message)) = channel.receive() {
messages.push(message);
self.global_stats.total_messages_delivered += 1;
}
}
}
messages
}
pub fn broadcast(&mut self, sender: AgentId, message_type: MessageType, payload: MessagePayload) -> Result<()> {
let receivers: Vec<AgentId> = self.channels.keys()
.map(|(_, receiver)| *receiver)
.collect::<BTreeSet<_>>()
.into_iter()
.filter(|&id| id != sender)
.collect();
for receiver in receivers {
let message = Message {
from: sender,
to: receiver,
msg_type: message_type.clone(),
payload: payload.clone(),
};
self.send_message(message)?;
}
Ok(())
}
pub fn create_broadcast_channel(&mut self, name: String, config: BroadcastConfig) -> Result<()> {
if self.broadcast_channels.contains_key(&name) {
return Err(SwarmError::channel("Broadcast channel already exists"));
}
let channel = BroadcastChannel::new(name.clone(), config);
self.broadcast_channels.insert(name, channel);
Ok(())
}
pub fn subscribe(&mut self, channel_name: &str, agent_id: AgentId) -> Result<()> {
let channel = self.broadcast_channels.get_mut(channel_name)
.ok_or_else(|| SwarmError::channel("Broadcast channel not found"))?;
channel.subscribe(agent_id)
}
pub fn unsubscribe(&mut self, channel_name: &str, agent_id: AgentId) -> Result<()> {
let channel = self.broadcast_channels.get_mut(channel_name)
.ok_or_else(|| SwarmError::channel("Broadcast channel not found"))?;
channel.unsubscribe(agent_id)
}
pub fn publish(&mut self, channel_name: &str, sender: AgentId, message_type: MessageType, payload: MessagePayload) -> Result<()> {
let channel = self.broadcast_channels.get_mut(channel_name)
.ok_or_else(|| SwarmError::channel("Broadcast channel not found"))?;
let message = Message {
from: sender,
to: AgentId::from(0), msg_type: message_type,
payload,
};
channel.publish(message)?;
self.global_stats.total_broadcasts += 1;
Ok(())
}
pub fn get_broadcasts(&mut self, agent_id: AgentId) -> Vec<Message> {
let mut messages = Vec::new();
for channel in self.broadcast_channels.values_mut() {
messages.extend(channel.get_messages(agent_id));
}
messages
}
pub fn global_stats(&self) -> &GlobalChannelStats {
&self.global_stats
}
pub fn channel_stats(&self, sender: AgentId, receiver: AgentId) -> Option<&ChannelStats> {
let key = (sender, receiver);
self.channels.get(&key).map(|channel| channel.stats())
}
pub fn cleanup(&mut self) {
self.channels.retain(|_, channel| !channel.is_empty() || channel.stats.messages_sent > 0);
for channel in self.broadcast_channels.values_mut() {
channel.cleanup();
}
}
}
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct GlobalChannelStats {
pub total_messages_sent: u64,
pub total_messages_delivered: u64,
pub total_broadcasts: u64,
pub active_channels: usize,
pub broadcast_channels: usize,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct BroadcastConfig {
pub max_subscribers: usize,
pub history_size: usize,
pub ordered: bool,
}
impl Default for BroadcastConfig {
fn default() -> Self {
Self {
max_subscribers: 100,
history_size: 1000,
ordered: true,
}
}
}
#[derive(Debug)]
pub struct BroadcastChannel {
pub name: String,
subscribers: Vec<AgentId>,
message_history: VecDeque<Message>,
agent_queues: BTreeMap<AgentId, VecDeque<Message>>,
config: BroadcastConfig,
}
impl BroadcastChannel {
pub fn new(name: String, config: BroadcastConfig) -> Self {
Self {
name,
subscribers: Vec::new(),
message_history: VecDeque::with_capacity(config.history_size),
agent_queues: BTreeMap::new(),
config,
}
}
pub fn subscribe(&mut self, agent_id: AgentId) -> Result<()> {
if self.subscribers.len() >= self.config.max_subscribers {
return Err(SwarmError::channel("Maximum subscribers reached"));
}
if !self.subscribers.contains(&agent_id) {
self.subscribers.push(agent_id);
self.agent_queues.insert(agent_id, VecDeque::new());
}
Ok(())
}
pub fn unsubscribe(&mut self, agent_id: AgentId) -> Result<()> {
self.subscribers.retain(|&id| id != agent_id);
self.agent_queues.remove(&agent_id);
Ok(())
}
pub fn publish(&mut self, message: Message) -> Result<()> {
if self.message_history.len() >= self.config.history_size {
self.message_history.pop_front();
}
self.message_history.push_back(message.clone());
for &subscriber in &self.subscribers {
if let Some(queue) = self.agent_queues.get_mut(&subscriber) {
let mut subscriber_message = message.clone();
subscriber_message.to = subscriber;
queue.push_back(subscriber_message);
}
}
Ok(())
}
pub fn get_messages(&mut self, agent_id: AgentId) -> Vec<Message> {
if let Some(queue) = self.agent_queues.get_mut(&agent_id) {
let messages = queue.drain(..).collect();
messages
} else {
Vec::new()
}
}
pub fn history(&self) -> &VecDeque<Message> {
&self.message_history
}
pub fn subscriber_count(&self) -> usize {
self.subscribers.len()
}
pub fn cleanup(&mut self) {
self.agent_queues.retain(|_, queue| !queue.is_empty());
}
}