|
@@ -31,31 +31,31 @@ pub enum Error {
|
|
pub struct Client {
|
|
pub struct Client {
|
|
pub url: String,
|
|
pub url: String,
|
|
|
|
|
|
- pub sender: mpsc::Sender<Request>,
|
|
|
|
|
|
+ pub send_to_socket: mpsc::Sender<Request>,
|
|
|
|
|
|
- receiver: broadcast::Receiver<(String, Response)>,
|
|
|
|
- stopper: oneshot::Sender<()>,
|
|
|
|
|
|
+ recv_from_socket: broadcast::Receiver<(Response, String)>,
|
|
|
|
+ stop_service: oneshot::Sender<()>,
|
|
}
|
|
}
|
|
|
|
|
|
impl Client {
|
|
impl Client {
|
|
pub fn new(url: &str) -> Result<Self, Error> {
|
|
pub fn new(url: &str) -> Result<Self, Error> {
|
|
- let (sender, receiver) = mpsc::channel(10_000);
|
|
|
|
- let (receiver, stopper) = Self::spawn(receiver, url)?;
|
|
|
|
|
|
+ let (send_to_socket, receiver) = mpsc::channel(10_000);
|
|
|
|
+ let (recv_from_socket, stop_service) = Self::spawn(receiver, url)?;
|
|
|
|
|
|
Ok(Self {
|
|
Ok(Self {
|
|
url: url.to_owned(),
|
|
url: url.to_owned(),
|
|
- sender,
|
|
|
|
- stopper,
|
|
|
|
- receiver,
|
|
|
|
|
|
+ send_to_socket,
|
|
|
|
+ stop_service,
|
|
|
|
+ recv_from_socket,
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
|
|
fn spawn(
|
|
fn spawn(
|
|
mut receiver: mpsc::Receiver<Request>,
|
|
mut receiver: mpsc::Receiver<Request>,
|
|
url_str: &str,
|
|
url_str: &str,
|
|
- ) -> Result<(broadcast::Receiver<(String, Response)>, oneshot::Sender<()>), Error> {
|
|
|
|
- let (response_sender, response_receiver) = broadcast::channel(10_000);
|
|
|
|
- let (stopper_sender, mut stopper_recv) = oneshot::channel();
|
|
|
|
|
|
+ ) -> Result<(broadcast::Receiver<(Response, String)>, oneshot::Sender<()>), Error> {
|
|
|
|
+ let (publish_to_listener, recv_from_socket) = broadcast::channel(10_000);
|
|
|
|
+ let (stop_service, mut stopper_recv) = oneshot::channel();
|
|
|
|
|
|
let url = url_str.to_owned();
|
|
let url = url_str.to_owned();
|
|
let url_parsed = Url::parse(&url)?;
|
|
let url_parsed = Url::parse(&url)?;
|
|
@@ -70,7 +70,7 @@ impl Client {
|
|
x.0
|
|
x.0
|
|
} else {
|
|
} else {
|
|
println!("{}: Failed to connect", url);
|
|
println!("{}: Failed to connect", url);
|
|
- sleep(Duration::from_secs(1)).await;
|
|
|
|
|
|
+ sleep(Duration::from_secs(5)).await;
|
|
continue;
|
|
continue;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -112,7 +112,7 @@ impl Client {
|
|
let msg: Result<Response, _> = serde_json::from_str(&msg);
|
|
let msg: Result<Response, _> = serde_json::from_str(&msg);
|
|
|
|
|
|
if let Ok(msg) = msg {
|
|
if let Ok(msg) = msg {
|
|
- if let Err(error) = response_sender.send((url.to_owned(), msg)) {
|
|
|
|
|
|
+ if let Err(error) = publish_to_listener.send((msg, url.to_owned())) {
|
|
println!("{}: Reconnecting client because of {}", url, error);
|
|
println!("{}: Reconnecting client because of {}", url, error);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -128,48 +128,46 @@ impl Client {
|
|
println!("{}: Disconnected", url);
|
|
println!("{}: Disconnected", url);
|
|
});
|
|
});
|
|
|
|
|
|
- Ok((response_receiver, stopper_sender))
|
|
|
|
|
|
+ Ok((recv_from_socket, stop_service))
|
|
}
|
|
}
|
|
|
|
|
|
pub fn is_running(&self) -> bool {
|
|
pub fn is_running(&self) -> bool {
|
|
- !self.stopper.is_closed()
|
|
|
|
|
|
+ !self.stop_service.is_closed()
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn subscribe(&self) -> broadcast::Receiver<(String, Response)> {
|
|
|
|
- self.receiver.resubscribe()
|
|
|
|
|
|
+ pub fn subscribe(&self) -> broadcast::Receiver<(Response, String)> {
|
|
|
|
+ self.recv_from_socket.resubscribe()
|
|
}
|
|
}
|
|
|
|
|
|
pub async fn send(&self, request: Request) -> Result<(), Error> {
|
|
pub async fn send(&self, request: Request) -> Result<(), Error> {
|
|
- Ok(self.sender.send(request).await?)
|
|
|
|
|
|
+ Ok(self.send_to_socket.send(request).await?)
|
|
}
|
|
}
|
|
|
|
|
|
pub async fn stop(self) {
|
|
pub async fn stop(self) {
|
|
- let _ = self.stopper.send(());
|
|
|
|
|
|
+ let _ = self.stop_service.send(());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
#[derive(Debug, Clone)]
|
|
pub struct Clients {
|
|
pub struct Clients {
|
|
clients: Arc<RwLock<HashMap<String, Client>>>,
|
|
clients: Arc<RwLock<HashMap<String, Client>>>,
|
|
- subscriptions: Arc<RwLock<Vec<broadcast::Receiver<(String, Response)>>>>,
|
|
|
|
}
|
|
}
|
|
|
|
|
|
impl Default for Clients {
|
|
impl Default for Clients {
|
|
fn default() -> Self {
|
|
fn default() -> Self {
|
|
Self {
|
|
Self {
|
|
clients: Arc::new(RwLock::new(HashMap::new())),
|
|
clients: Arc::new(RwLock::new(HashMap::new())),
|
|
- subscriptions: Arc::new(RwLock::new(vec![])),
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
impl Clients {
|
|
impl Clients {
|
|
- pub async fn recv(&self) -> Option<(String, Response)> {
|
|
|
|
|
|
+ pub async fn recv(&self) -> Option<(Response, String)> {
|
|
let mut subscriptions = self
|
|
let mut subscriptions = self
|
|
- .subscriptions
|
|
|
|
|
|
+ .clients
|
|
.read()
|
|
.read()
|
|
.iter()
|
|
.iter()
|
|
- .map(|s| s.resubscribe())
|
|
|
|
|
|
+ .map(|(_, c)| c.subscribe())
|
|
.collect::<Vec<_>>();
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
let mut futures = FuturesUnordered::new();
|
|
let mut futures = FuturesUnordered::new();
|
|
@@ -184,8 +182,13 @@ impl Clients {
|
|
None
|
|
None
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- pub fn try_recv(&self) -> Option<(String, Response)> {
|
|
|
|
- let mut subscriptions = self.subscriptions.write();
|
|
|
|
|
|
+ pub fn try_recv(&self) -> Option<(Response, String)> {
|
|
|
|
+ let mut subscriptions = self
|
|
|
|
+ .clients
|
|
|
|
+ .read()
|
|
|
|
+ .iter()
|
|
|
|
+ .map(|(_, c)| c.subscribe())
|
|
|
|
+ .collect::<Vec<_>>();
|
|
for sub in subscriptions.iter_mut() {
|
|
for sub in subscriptions.iter_mut() {
|
|
if let Ok(msg) = sub.try_recv() {
|
|
if let Ok(msg) = sub.try_recv() {
|
|
return Some(msg);
|
|
return Some(msg);
|
|
@@ -196,7 +199,6 @@ impl Clients {
|
|
|
|
|
|
pub fn check_active_connections(&self) -> usize {
|
|
pub fn check_active_connections(&self) -> usize {
|
|
let mut clients = self.clients.write();
|
|
let mut clients = self.clients.write();
|
|
- let mut subscriptions = self.subscriptions.write();
|
|
|
|
let mut to_remove = vec![];
|
|
let mut to_remove = vec![];
|
|
for (url, client) in clients.iter() {
|
|
for (url, client) in clients.iter() {
|
|
if !client.is_running() {
|
|
if !client.is_running() {
|
|
@@ -208,7 +210,6 @@ impl Clients {
|
|
clients.remove(url);
|
|
clients.remove(url);
|
|
}
|
|
}
|
|
|
|
|
|
- subscriptions.retain(|s| s.len() > 0);
|
|
|
|
clients.len()
|
|
clients.len()
|
|
}
|
|
}
|
|
|
|
|
|
@@ -217,7 +218,7 @@ impl Clients {
|
|
.clients
|
|
.clients
|
|
.read()
|
|
.read()
|
|
.iter()
|
|
.iter()
|
|
- .map(|(_, c)| c.sender.clone())
|
|
|
|
|
|
+ .map(|(_, c)| c.send_to_socket.clone())
|
|
.collect::<Vec<mpsc::Sender<_>>>();
|
|
.collect::<Vec<mpsc::Sender<_>>>();
|
|
|
|
|
|
for sender in senders.iter() {
|
|
for sender in senders.iter() {
|
|
@@ -231,10 +232,7 @@ impl Clients {
|
|
false
|
|
false
|
|
} else {
|
|
} else {
|
|
println!("Connecting to {}", url);
|
|
println!("Connecting to {}", url);
|
|
- let client = Client::new(url)?;
|
|
|
|
- let mut subscriptions = self.subscriptions.write();
|
|
|
|
- subscriptions.push(client.subscribe());
|
|
|
|
- clients.insert(url.to_owned(), client);
|
|
|
|
|
|
+ clients.insert(url.to_owned(), Client::new(url)?);
|
|
true
|
|
true
|
|
})
|
|
})
|
|
}
|
|
}
|