#[cfg(not(feature = "use-mock-crust"))]
use maidsafe_utilities::thread::RaiiThreadJoiner;
use sodiumoxide;
#[cfg(feature = "use-mock-crust")]
use std::cell::RefCell;
use std::sync::mpsc::{Receiver, Sender, channel};
use id::FullId;
use action::Action;
use event::Event;
use core::Core;
use data::{Data, DataRequest};
use error::{InterfaceError, RoutingError};
use authority::Authority;
use messages::RequestContent;
use types::MessageId;
type RoutingResult = Result<(), RoutingError>;
pub struct Client {
interface_result_tx: Sender<Result<(), InterfaceError>>,
interface_result_rx: Receiver<Result<(), InterfaceError>>,
action_sender: ::types::RoutingActionSender,
#[cfg(feature = "use-mock-crust")]
core: RefCell<Core>,
#[cfg(not(feature = "use-mock-crust"))]
_raii_joiner: ::maidsafe_utilities::thread::RaiiThreadJoiner,
}
impl Client {
#[cfg(not(feature = "use-mock-crust"))]
pub fn new(event_sender: Sender<Event>,
keys: Option<FullId>,
use_data_cache: bool)
-> Result<Client, RoutingError> {
sodiumoxide::init();
let (action_sender, mut core) = Core::new(event_sender, true, keys, use_data_cache);
let (tx, rx) = channel();
let raii_joiner = RaiiThreadJoiner::new(thread!("Client thread", move || {
core.run();
}));
Ok(Client {
interface_result_tx: tx,
interface_result_rx: rx,
action_sender: action_sender,
_raii_joiner: raii_joiner,
})
}
#[cfg(feature = "use-mock-crust")]
pub fn new(event_sender: Sender<Event>,
keys: Option<FullId>,
use_data_cache: bool)
-> Result<Client, RoutingError> {
sodiumoxide::init();
let (action_sender, core) = Core::new(event_sender, true, keys, use_data_cache);
let (tx, rx) = channel();
Ok(Client {
interface_result_tx: tx,
interface_result_rx: rx,
action_sender: action_sender,
core: RefCell::new(core),
})
}
#[cfg(feature = "use-mock-crust")]
#[allow(missing_docs)]
pub fn poll(&self) -> bool {
self.core.borrow_mut().poll()
}
pub fn send_get_request(&mut self,
dst: Authority,
data_request: DataRequest,
message_id: MessageId)
-> Result<(), InterfaceError> {
self.send_action(RequestContent::Get(data_request, message_id), dst)
}
pub fn send_put_request(&self,
dst: Authority,
data: Data,
message_id: MessageId)
-> Result<(), InterfaceError> {
self.send_action(RequestContent::Put(data, message_id), dst)
}
pub fn send_post_request(&self,
dst: Authority,
data: Data,
message_id: MessageId)
-> Result<(), InterfaceError> {
self.send_action(RequestContent::Post(data, message_id), dst)
}
pub fn send_delete_request(&self,
dst: Authority,
data: Data,
message_id: MessageId)
-> Result<(), InterfaceError> {
self.send_action(RequestContent::Delete(data, message_id), dst)
}
fn send_action(&self, content: RequestContent, dst: Authority) -> Result<(), InterfaceError> {
let action = Action::ClientSendRequest {
content: content,
dst: dst,
result_tx: self.interface_result_tx.clone(),
};
try!(self.action_sender.send(action));
self.receive_action_result()
}
#[cfg(not(feature = "use-mock-crust"))]
fn receive_action_result(&self) -> Result<(), InterfaceError> {
try!(self.interface_result_rx.recv())
}
#[cfg(feature = "use-mock-crust")]
fn receive_action_result(&self) -> Result<(), InterfaceError> {
while self.poll() {}
try!(self.interface_result_rx.recv())
}
}
impl Drop for Client {
fn drop(&mut self) {
if let Err(err) = self.action_sender.send(Action::Terminate) {
error!("Error {:?} sending event to Core", err);
}
}
}