|
@@ -3,7 +3,13 @@ use futures::Future;
|
|
use futures_util::{SinkExt, StreamExt};
|
|
use futures_util::{SinkExt, StreamExt};
|
|
use nostr_rs_types::{Request, Response};
|
|
use nostr_rs_types::{Request, Response};
|
|
use parking_lot::RwLock;
|
|
use parking_lot::RwLock;
|
|
-use std::{pin::Pin, sync::Arc};
|
|
|
|
|
|
+use std::{
|
|
|
|
+ pin::Pin,
|
|
|
|
+ sync::{
|
|
|
|
+ atomic::{AtomicBool, Ordering::Relaxed},
|
|
|
|
+ Arc,
|
|
|
|
+ },
|
|
|
|
+};
|
|
use tokio::{
|
|
use tokio::{
|
|
sync::{mpsc, oneshot},
|
|
sync::{mpsc, oneshot},
|
|
time::{sleep, timeout, Duration},
|
|
time::{sleep, timeout, Duration},
|
|
@@ -18,6 +24,7 @@ pub struct Relayer {
|
|
pub url: String,
|
|
pub url: String,
|
|
/// Sender to the relayer. This can be used to send a Requests to this relayer
|
|
/// Sender to the relayer. This can be used to send a Requests to this relayer
|
|
pub send_to_socket: mpsc::Sender<Request>,
|
|
pub send_to_socket: mpsc::Sender<Request>,
|
|
|
|
+ is_connected: Arc<AtomicBool>,
|
|
/// This sender signals to background connection to stop
|
|
/// This sender signals to background connection to stop
|
|
stop_service: oneshot::Sender<()>,
|
|
stop_service: oneshot::Sender<()>,
|
|
}
|
|
}
|
|
@@ -40,6 +47,7 @@ impl Relayer {
|
|
+ 'static,
|
|
+ 'static,
|
|
{
|
|
{
|
|
let (send_to_socket, receiver) = mpsc::channel(100_000);
|
|
let (send_to_socket, receiver) = mpsc::channel(100_000);
|
|
|
|
+ let is_connected = Arc::new(AtomicBool::new(false));
|
|
let stop_service = Self::spawn_background_client(
|
|
let stop_service = Self::spawn_background_client(
|
|
broadcast_to_listeners,
|
|
broadcast_to_listeners,
|
|
sent_messages,
|
|
sent_messages,
|
|
@@ -47,11 +55,13 @@ impl Relayer {
|
|
receiver,
|
|
receiver,
|
|
url,
|
|
url,
|
|
max_connections_attempts,
|
|
max_connections_attempts,
|
|
|
|
+ is_connected.clone(),
|
|
on_connection,
|
|
on_connection,
|
|
)?;
|
|
)?;
|
|
|
|
|
|
Ok(Self {
|
|
Ok(Self {
|
|
url: url.to_owned(),
|
|
url: url.to_owned(),
|
|
|
|
+ is_connected,
|
|
send_to_socket,
|
|
send_to_socket,
|
|
stop_service,
|
|
stop_service,
|
|
})
|
|
})
|
|
@@ -64,6 +74,7 @@ impl Relayer {
|
|
mut receiver: mpsc::Receiver<Request>,
|
|
mut receiver: mpsc::Receiver<Request>,
|
|
url_str: &str,
|
|
url_str: &str,
|
|
max_connections_attempts: u16,
|
|
max_connections_attempts: u16,
|
|
|
|
+ is_connected: Arc<AtomicBool>,
|
|
on_connection: Option<F>,
|
|
on_connection: Option<F>,
|
|
) -> Result<oneshot::Sender<()>, Error>
|
|
) -> Result<oneshot::Sender<()>, Error>
|
|
where
|
|
where
|
|
@@ -117,6 +128,7 @@ impl Relayer {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
msg = timeout(Duration::from_secs(NO_ACTIVITY_TIMEOUT_SECS), socket.next()) => {
|
|
msg = timeout(Duration::from_secs(NO_ACTIVITY_TIMEOUT_SECS), socket.next()) => {
|
|
|
|
+ is_connected.store(true, Relaxed);
|
|
let msg = if let Ok(Some(Ok(msg))) = msg {
|
|
let msg = if let Ok(Some(Ok(msg))) = msg {
|
|
match msg {
|
|
match msg {
|
|
Message::Text(text) => text,
|
|
Message::Text(text) => text,
|
|
@@ -157,6 +169,9 @@ impl Relayer {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ is_connected.store(false, Relaxed);
|
|
|
|
+
|
|
// Throttle down to not spam the server with reconnections
|
|
// Throttle down to not spam the server with reconnections
|
|
sleep(Duration::from_millis(500)).await;
|
|
sleep(Duration::from_millis(500)).await;
|
|
}
|
|
}
|
|
@@ -167,11 +182,19 @@ impl Relayer {
|
|
Ok(stop_service)
|
|
Ok(stop_service)
|
|
}
|
|
}
|
|
|
|
|
|
- /// Checks if the relayer background connection is running
|
|
|
|
|
|
+ /// Checks if the relayer background connection is running. It is not
|
|
|
|
+ /// guaranteed there is an active connection, it may be in the process of
|
|
|
|
+ /// reconnecting.
|
|
pub fn is_running(&self) -> bool {
|
|
pub fn is_running(&self) -> bool {
|
|
!self.stop_service.is_closed()
|
|
!self.stop_service.is_closed()
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// Checks if the relayer is connected. It is guaranteed that the relayer is
|
|
|
|
+ /// connected if this method returns true.
|
|
|
|
+ pub fn is_connected(&self) -> bool {
|
|
|
|
+ self.is_connected.load(Relaxed)
|
|
|
|
+ }
|
|
|
|
+
|
|
/// Sends a requests to this relayer
|
|
/// Sends a requests to this relayer
|
|
pub async fn send(&self, request: Request) -> Result<(), Error> {
|
|
pub async fn send(&self, request: Request) -> Result<(), Error> {
|
|
Ok(self.send_to_socket.send(request).await?)
|
|
Ok(self.send_to_socket.send(request).await?)
|