|
@@ -1,4 +1,5 @@
|
|
|
-use async_dup::Arc;
|
|
|
|
|
|
|
+use async_std::sync::Mutex;
|
|
|
|
|
+use std::sync::Arc;
|
|
|
use log::*;
|
|
use log::*;
|
|
|
use rand::seq::SliceRandom;
|
|
use rand::seq::SliceRandom;
|
|
|
use smol::{Async, Executor};
|
|
use smol::{Async, Executor};
|
|
@@ -14,18 +15,25 @@ pub struct ClientProtocol {
|
|
|
send_sx: async_channel::Sender<net::Message>,
|
|
send_sx: async_channel::Sender<net::Message>,
|
|
|
send_rx: async_channel::Receiver<net::Message>,
|
|
send_rx: async_channel::Receiver<net::Message>,
|
|
|
connections: ConnectionsMap,
|
|
connections: ConnectionsMap,
|
|
|
- main_process: Option<smol::Task<()>>,
|
|
|
|
|
|
|
+ main_process: Mutex<Option<smol::Task<()>>>,
|
|
|
|
|
+
|
|
|
|
|
+ accept_addr: Option<SocketAddr>,
|
|
|
|
|
+ stored_addrs: AddrsStorage,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
impl ClientProtocol {
|
|
impl ClientProtocol {
|
|
|
- pub fn new(connections: ConnectionsMap) -> Self {
|
|
|
|
|
|
|
+ pub fn new(connections: ConnectionsMap, accept_addr: Option<SocketAddr>,
|
|
|
|
|
+ stored_addrs: AddrsStorage,
|
|
|
|
|
+ ) -> Arc<Self> {
|
|
|
let (send_sx, send_rx) = async_channel::unbounded::<net::Message>();
|
|
let (send_sx, send_rx) = async_channel::unbounded::<net::Message>();
|
|
|
- Self {
|
|
|
|
|
|
|
+ Arc::new(Self {
|
|
|
send_sx,
|
|
send_sx,
|
|
|
send_rx,
|
|
send_rx,
|
|
|
connections,
|
|
connections,
|
|
|
- main_process: None,
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ main_process: Mutex::new(None),
|
|
|
|
|
+ accept_addr,
|
|
|
|
|
+ stored_addrs
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pub fn get_send_pipe(&self) -> async_channel::Sender<net::Message> {
|
|
pub fn get_send_pipe(&self) -> async_channel::Sender<net::Message> {
|
|
@@ -33,6 +41,7 @@ impl ClientProtocol {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async fn fetch_random_addr(
|
|
async fn fetch_random_addr(
|
|
|
|
|
+ self: Arc<Self>,
|
|
|
accept_addr: &Option<SocketAddr>,
|
|
accept_addr: &Option<SocketAddr>,
|
|
|
stored_addrs: &AddrsStorage,
|
|
stored_addrs: &AddrsStorage,
|
|
|
connections: &ConnectionsMap,
|
|
connections: &ConnectionsMap,
|
|
@@ -58,19 +67,15 @@ impl ClientProtocol {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pub async fn start(
|
|
pub async fn start(
|
|
|
- &mut self,
|
|
|
|
|
- accept_addr: Option<SocketAddr>,
|
|
|
|
|
- stored_addrs: AddrsStorage,
|
|
|
|
|
|
|
+ self: Arc<Self>,
|
|
|
executor: Arc<Executor<'_>>,
|
|
executor: Arc<Executor<'_>>,
|
|
|
) {
|
|
) {
|
|
|
- let connections = self.connections.clone();
|
|
|
|
|
- let (send_sx, send_rx) = (self.send_sx.clone(), self.send_rx.clone());
|
|
|
|
|
-
|
|
|
|
|
let executor2 = executor.clone();
|
|
let executor2 = executor.clone();
|
|
|
|
|
+ let self2 = self.clone();
|
|
|
|
|
|
|
|
- self.main_process = Some(executor.spawn(async move {
|
|
|
|
|
|
|
+ *self2.main_process.lock().await = Some(executor.spawn(async move {
|
|
|
loop {
|
|
loop {
|
|
|
- let addr = match stored_addrs.lock().await.choose(&mut rand_core::OsRng) {
|
|
|
|
|
|
|
+ let addr = match self.stored_addrs.lock().await.choose(&mut rand_core::OsRng) {
|
|
|
Some(addr) => addr.clone(),
|
|
Some(addr) => addr.clone(),
|
|
|
None => {
|
|
None => {
|
|
|
debug!("No addresses in store. Sleeping for 2 secs before retrying...");
|
|
debug!("No addresses in store. Sleeping for 2 secs before retrying...");
|
|
@@ -78,10 +83,10 @@ impl ClientProtocol {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
- if connections.lock().await.contains_key(&addr) {
|
|
|
|
|
|
|
+ if self.connections.lock().await.contains_key(&addr) {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
- if let Some(accept_addr) = accept_addr {
|
|
|
|
|
|
|
+ if let Some(accept_addr) = self.accept_addr {
|
|
|
if addr == accept_addr {
|
|
if addr == accept_addr {
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
@@ -89,12 +94,8 @@ impl ClientProtocol {
|
|
|
|
|
|
|
|
debug!("Attempting connect to {}", addr);
|
|
debug!("Attempting connect to {}", addr);
|
|
|
|
|
|
|
|
- Self::try_connect_process(
|
|
|
|
|
|
|
+ self.try_connect_process(
|
|
|
addr,
|
|
addr,
|
|
|
- connections.clone(),
|
|
|
|
|
- accept_addr.clone(),
|
|
|
|
|
- stored_addrs.clone(),
|
|
|
|
|
- (send_sx.clone(), send_rx.clone()),
|
|
|
|
|
executor2.clone(),
|
|
executor2.clone(),
|
|
|
)
|
|
)
|
|
|
.await;
|
|
.await;
|
|
@@ -106,28 +107,20 @@ impl ClientProtocol {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pub async fn start_manual(
|
|
pub async fn start_manual(
|
|
|
- &mut self,
|
|
|
|
|
|
|
+ self: Arc<Self>,
|
|
|
remote_addr: SocketAddr,
|
|
remote_addr: SocketAddr,
|
|
|
- accept_addr: Option<SocketAddr>,
|
|
|
|
|
- stored_addrs: AddrsStorage,
|
|
|
|
|
executor: Arc<Executor<'_>>,
|
|
executor: Arc<Executor<'_>>,
|
|
|
) {
|
|
) {
|
|
|
- let connections = self.connections.clone();
|
|
|
|
|
- let (send_sx, send_rx) = (self.send_sx.clone(), self.send_rx.clone());
|
|
|
|
|
-
|
|
|
|
|
let executor2 = executor.clone();
|
|
let executor2 = executor.clone();
|
|
|
|
|
+ let self2 = self.clone();
|
|
|
|
|
|
|
|
- self.main_process = Some(executor.spawn(async move {
|
|
|
|
|
|
|
+ *self2.main_process.lock().await = Some(executor.spawn(async move {
|
|
|
loop {
|
|
loop {
|
|
|
for _ in 0..4 {
|
|
for _ in 0..4 {
|
|
|
debug!("Attempting connect to {}", remote_addr);
|
|
debug!("Attempting connect to {}", remote_addr);
|
|
|
|
|
|
|
|
- Self::try_connect_process(
|
|
|
|
|
|
|
+ self.try_connect_process(
|
|
|
remote_addr,
|
|
remote_addr,
|
|
|
- connections.clone(),
|
|
|
|
|
- accept_addr.clone(),
|
|
|
|
|
- stored_addrs.clone(),
|
|
|
|
|
- (send_sx.clone(), send_rx.clone()),
|
|
|
|
|
executor2.clone(),
|
|
executor2.clone(),
|
|
|
)
|
|
)
|
|
|
.await;
|
|
.await;
|
|
@@ -138,25 +131,15 @@ impl ClientProtocol {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pub async fn try_connect_process(
|
|
pub async fn try_connect_process(
|
|
|
|
|
+ &self,
|
|
|
address: SocketAddr,
|
|
address: SocketAddr,
|
|
|
- connections: ConnectionsMap,
|
|
|
|
|
- accept_addr: Option<SocketAddr>,
|
|
|
|
|
- stored_addrs: AddrsStorage,
|
|
|
|
|
- (send_sx, send_rx): (
|
|
|
|
|
- async_channel::Sender<net::Message>,
|
|
|
|
|
- async_channel::Receiver<net::Message>,
|
|
|
|
|
- ),
|
|
|
|
|
executor: Arc<Executor<'_>>,
|
|
executor: Arc<Executor<'_>>,
|
|
|
) {
|
|
) {
|
|
|
match Async::<TcpStream>::connect(address.clone()).await {
|
|
match Async::<TcpStream>::connect(address.clone()).await {
|
|
|
Ok(stream) => {
|
|
Ok(stream) => {
|
|
|
- let _ = Self::handle_connect(
|
|
|
|
|
|
|
+ let _ = self.handle_connect(
|
|
|
stream,
|
|
stream,
|
|
|
- stored_addrs.clone(),
|
|
|
|
|
- connections,
|
|
|
|
|
address,
|
|
address,
|
|
|
- (send_sx.clone(), send_rx.clone()),
|
|
|
|
|
- accept_addr,
|
|
|
|
|
executor,
|
|
executor,
|
|
|
)
|
|
)
|
|
|
.await;
|
|
.await;
|
|
@@ -168,32 +151,22 @@ impl ClientProtocol {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async fn handle_connect(
|
|
async fn handle_connect(
|
|
|
|
|
+ &self,
|
|
|
stream: Async<TcpStream>,
|
|
stream: Async<TcpStream>,
|
|
|
- stored_addrs: AddrsStorage,
|
|
|
|
|
- connections: ConnectionsMap,
|
|
|
|
|
address: SocketAddr,
|
|
address: SocketAddr,
|
|
|
- (send_sx, send_rx): (
|
|
|
|
|
- async_channel::Sender<net::Message>,
|
|
|
|
|
- async_channel::Receiver<net::Message>,
|
|
|
|
|
- ),
|
|
|
|
|
- accept_addr: Option<SocketAddr>,
|
|
|
|
|
executor: Arc<Executor<'_>>,
|
|
executor: Arc<Executor<'_>>,
|
|
|
) -> Result<()> {
|
|
) -> Result<()> {
|
|
|
debug!("Connected to {}", address);
|
|
debug!("Connected to {}", address);
|
|
|
|
|
|
|
|
let stream = async_dup::Arc::new(stream);
|
|
let stream = async_dup::Arc::new(stream);
|
|
|
- connections
|
|
|
|
|
|
|
+ self.connections
|
|
|
.lock()
|
|
.lock()
|
|
|
.await
|
|
.await
|
|
|
- .insert(address.clone(), send_sx.clone());
|
|
|
|
|
|
|
+ .insert(address.clone(), self.send_sx.clone());
|
|
|
|
|
|
|
|
// Run event loop
|
|
// Run event loop
|
|
|
- match Self::event_loop_process(
|
|
|
|
|
|
|
+ match self.event_loop_process(
|
|
|
stream,
|
|
stream,
|
|
|
- stored_addrs,
|
|
|
|
|
- (send_sx, send_rx),
|
|
|
|
|
- accept_addr,
|
|
|
|
|
- connections.clone(),
|
|
|
|
|
executor,
|
|
executor,
|
|
|
)
|
|
)
|
|
|
.await
|
|
.await
|
|
@@ -205,7 +178,7 @@ impl ClientProtocol {
|
|
|
warn!("Server disconnected: {}", err);
|
|
warn!("Server disconnected: {}", err);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- connections.lock().await.remove(&address);
|
|
|
|
|
|
|
+ self.connections.lock().await.remove(&address);
|
|
|
Ok(())
|
|
Ok(())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -225,30 +198,24 @@ impl ClientProtocol {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
pub async fn event_loop_process(
|
|
pub async fn event_loop_process(
|
|
|
|
|
+ &self,
|
|
|
mut stream: net::AsyncTcpStream,
|
|
mut stream: net::AsyncTcpStream,
|
|
|
- stored_addrs: AddrsStorage,
|
|
|
|
|
- (send_sx, send_rx): (
|
|
|
|
|
- async_channel::Sender<net::Message>,
|
|
|
|
|
- async_channel::Receiver<net::Message>,
|
|
|
|
|
- ),
|
|
|
|
|
- accept_addr: Option<SocketAddr>,
|
|
|
|
|
- connections: ConnectionsMap,
|
|
|
|
|
executor: Arc<Executor<'_>>,
|
|
executor: Arc<Executor<'_>>,
|
|
|
) -> Result<()> {
|
|
) -> Result<()> {
|
|
|
let inactivity_timer = net::InactivityTimer::new(executor.clone());
|
|
let inactivity_timer = net::InactivityTimer::new(executor.clone());
|
|
|
|
|
|
|
|
let clock = Arc::new(AtomicU64::new(0));
|
|
let clock = Arc::new(AtomicU64::new(0));
|
|
|
- let send_sx2 = send_sx.clone();
|
|
|
|
|
|
|
+ let send_sx2 = self.send_sx.clone();
|
|
|
let clock2 = clock.clone();
|
|
let clock2 = clock.clone();
|
|
|
let ping_task = executor.spawn(protocol_base::repeat_ping(send_sx2, clock2));
|
|
let ping_task = executor.spawn(protocol_base::repeat_ping(send_sx2, clock2));
|
|
|
|
|
|
|
|
let mut send_addr_task = None;
|
|
let mut send_addr_task = None;
|
|
|
- if let Some(accept_addr) = accept_addr {
|
|
|
|
|
- send_addr_task = Some(executor.spawn(Self::send_addr(send_sx.clone(), accept_addr)));
|
|
|
|
|
|
|
+ if let Some(accept_addr) = self.accept_addr {
|
|
|
|
|
+ send_addr_task = Some(executor.spawn(Self::send_addr(self.send_sx.clone(), accept_addr.clone())));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
loop {
|
|
loop {
|
|
|
- let event = net::select_event(&mut stream, &send_rx, &inactivity_timer).await?;
|
|
|
|
|
|
|
+ let event = net::select_event(&mut stream, &self.send_rx, &inactivity_timer).await?;
|
|
|
|
|
|
|
|
match event {
|
|
match event {
|
|
|
net::Event::Send(message) => {
|
|
net::Event::Send(message) => {
|
|
@@ -258,10 +225,10 @@ impl ClientProtocol {
|
|
|
inactivity_timer.reset().await?;
|
|
inactivity_timer.reset().await?;
|
|
|
protocol_base::protocol(
|
|
protocol_base::protocol(
|
|
|
message,
|
|
message,
|
|
|
- &stored_addrs,
|
|
|
|
|
- &send_sx,
|
|
|
|
|
|
|
+ &self.stored_addrs,
|
|
|
|
|
+ &self.send_sx,
|
|
|
Some(&clock),
|
|
Some(&clock),
|
|
|
- connections.clone(),
|
|
|
|
|
|
|
+ self.connections.clone(),
|
|
|
)
|
|
)
|
|
|
.await?;
|
|
.await?;
|
|
|
}
|
|
}
|