pub mod bucket;
pub mod config;
pub mod error;
pub mod handler;
pub mod message;
pub mod node;
pub mod record;
pub mod router;
pub mod signaling;
pub mod switch;
pub mod topic;
pub mod transaction;
pub mod util;
use config::Config;
use config::Signaling as CSig;
use error::Error;
use handler::Listener;
use message::Message;
use node::Address;
pub use node::{Center, ToAddress};
use record::RecordBucket;
use router::Safe;
use signaling::Signaling;
use switch::Switch;
use topic::Simple;
pub use topic::Topic;
use transaction::Class;
pub use transaction::Transaction;
use util::Channel;
pub struct Interface {
pub center: Center,
switch: Channel<InterfaceAction>,
}
pub enum InterfaceAction {
Shutdown,
Message(Transaction),
Subscribe(Simple),
}
impl Interface {
pub fn new(config: Config, center: Center) -> Result<Self, Error> {
let bucket = RecordBucket::new();
let (switch1, switch2) = Channel::<InterfaceAction>::new();
let (listener1, listener2) = Channel::<Transaction>::new();
let (signaling1, signaling2) = Channel::<signaling::SignalingAction>::new();
let table = Safe::new(config.replication, center.clone());
let signaling = CSig::new(config.signaling, config.port);
let listener = Listener::new(
center.clone(),
listener1,
config.replication,
table.clone(),
signaling,
)?;
let switch = Switch::new(
listener2,
switch1,
signaling1,
center.clone(),
table.clone(),
bucket.clone(),
)?;
let signaling = Signaling::new(signaling2, table.clone());
log::info!("actaeon is starting up!");
listener.start();
switch.start();
signaling.start();
Ok(Self {
center,
switch: switch2,
})
}
pub fn subscribe(&self, addr: &Address) -> Topic {
let (c1, c2) = Channel::new();
let local = Topic::new(addr.clone(), c1, Vec::new(), self.center.public.clone());
let remote = Simple::new(addr.clone(), c2);
let _ = self.switch.send(InterfaceAction::Subscribe(remote));
local
}
pub fn send(&self, transaction: Transaction) -> Result<(), Error> {
let action = InterfaceAction::Message(transaction);
self.switch.send(action)
}
pub fn try_recv(&self) -> Option<Transaction> {
if let Some(action) = self.switch.try_recv() {
match action {
InterfaceAction::Message(t) => Some(t),
_ => None,
}
} else {
None
}
}
pub fn recv(&self) -> Option<Transaction> {
loop {
if let Some(action) = self.switch.recv() {
match action {
InterfaceAction::Message(t) => {
return Some(t);
}
_ => {
continue;
}
}
} else {
return None;
}
}
}
pub fn message(&self, target: Address, body: Vec<u8>) -> Result<(), Error> {
let message = Message::new(
Class::Action,
self.center.public.clone(),
target,
Address::default(),
body,
);
let action = InterfaceAction::Message(Transaction::new(message));
self.switch.send(action)
}
}