|
@@ -1,4 +1,8 @@
|
|
-use crate::{connection::ConnectionId, subscription::SubscriptionManager, Connection, Error};
|
|
|
|
|
|
+use crate::{
|
|
|
|
+ connection::{ConnectionId, LocalConnection},
|
|
|
|
+ subscription::SubscriptionManager,
|
|
|
|
+ Connection, Error,
|
|
|
|
+};
|
|
use futures_util::StreamExt;
|
|
use futures_util::StreamExt;
|
|
use nostr_rs_client::{Error as ClientError, Pool};
|
|
use nostr_rs_client::{Error as ClientError, Pool};
|
|
use nostr_rs_storage_base::Storage;
|
|
use nostr_rs_storage_base::Storage;
|
|
@@ -21,9 +25,10 @@ pub struct Relayer<T: Storage + Send + Sync + 'static> {
|
|
/// relayer just a dumb proxy (that can be useful for privacy) but it won't
|
|
/// relayer just a dumb proxy (that can be useful for privacy) but it won't
|
|
/// be able to perform any optimization like prefetching content while offline
|
|
/// be able to perform any optimization like prefetching content while offline
|
|
storage: Option<T>,
|
|
storage: Option<T>,
|
|
- /// x
|
|
|
|
|
|
+ /// Subscription manager
|
|
subscriptions: Arc<SubscriptionManager>,
|
|
subscriptions: Arc<SubscriptionManager>,
|
|
- clients: RwLock<HashMap<ConnectionId, Connection>>,
|
|
|
|
|
|
+ /// List of all active connections
|
|
|
|
+ connections: RwLock<HashMap<ConnectionId, Connection>>,
|
|
/// This Sender can be used to send requests from anywhere to the relayer.
|
|
/// This Sender can be used to send requests from anywhere to the relayer.
|
|
send_to_relayer: Sender<(ConnectionId, Request)>,
|
|
send_to_relayer: Sender<(ConnectionId, Request)>,
|
|
/// This Receiver is the relayer the way the relayer receives messages
|
|
/// This Receiver is the relayer the way the relayer receives messages
|
|
@@ -37,7 +42,7 @@ pub struct Relayer<T: Storage + Send + Sync + 'static> {
|
|
impl<T: Storage + Send + Sync + 'static> Drop for Relayer<T> {
|
|
impl<T: Storage + Send + Sync + 'static> Drop for Relayer<T> {
|
|
fn drop(&mut self) {
|
|
fn drop(&mut self) {
|
|
if let Some((_, handle)) = self.client_pool.take() {
|
|
if let Some((_, handle)) = self.client_pool.take() {
|
|
- let _ = handle.abort();
|
|
|
|
|
|
+ handle.abort();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -58,7 +63,7 @@ impl<T: Storage + Send + Sync + 'static> Relayer<T> {
|
|
subscriptions: Default::default(),
|
|
subscriptions: Default::default(),
|
|
send_to_relayer: sender.clone(),
|
|
send_to_relayer: sender.clone(),
|
|
relayer_receiver: Some(receiver),
|
|
relayer_receiver: Some(receiver),
|
|
- clients: Default::default(),
|
|
|
|
|
|
+ connections: Default::default(),
|
|
client_pool: if let Some(client_pool) = client_pool {
|
|
client_pool: if let Some(client_pool) = client_pool {
|
|
Some(Self::handle_client_pool(client_pool, sender)?)
|
|
Some(Self::handle_client_pool(client_pool, sender)?)
|
|
} else {
|
|
} else {
|
|
@@ -99,12 +104,12 @@ impl<T: Storage + Send + Sync + 'static> Relayer<T> {
|
|
if let Some(storage) = this.storage.as_ref() {
|
|
if let Some(storage) = this.storage.as_ref() {
|
|
let _ = storage.store_local_event(&event).await;
|
|
let _ = storage.store_local_event(&event).await;
|
|
}
|
|
}
|
|
- this.broadcast(&event.deref()).await;
|
|
|
|
|
|
+ this.broadcast(event.deref()).await;
|
|
}
|
|
}
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
- let connections = this.clients.read().await;
|
|
|
|
|
|
+ let connections = this.connections.read().await;
|
|
let connection = if let Some(connection) = connections.get(&conn_id) {
|
|
let connection = if let Some(connection) = connections.get(&conn_id) {
|
|
connection
|
|
connection
|
|
} else {
|
|
} else {
|
|
@@ -160,6 +165,15 @@ impl<T: Storage + Send + Sync + 'static> Relayer<T> {
|
|
&self.storage
|
|
&self.storage
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// Adds a new local connection to the list of active connections.
|
|
|
|
+ pub async fn create_new_local_connection(&self) -> LocalConnection {
|
|
|
|
+ let (conn, receiver) = Connection::new_local_connection();
|
|
|
|
+ let conn_id = conn.get_conn_id();
|
|
|
|
+ self.connections.write().await.insert(conn_id, conn);
|
|
|
|
+
|
|
|
|
+ (conn_id, receiver, self.send_to_relayer.clone()).into()
|
|
|
|
+ }
|
|
|
|
+
|
|
/// Adds a new TpStream and adds it to the list of active connections.
|
|
/// Adds a new TpStream and adds it to the list of active connections.
|
|
///
|
|
///
|
|
/// This function will spawn the client's loop to receive incoming messages and send those messages
|
|
/// This function will spawn the client's loop to receive incoming messages and send those messages
|
|
@@ -168,11 +182,11 @@ impl<T: Storage + Send + Sync + 'static> Relayer<T> {
|
|
disconnection_notify: Option<mpsc::Sender<ConnectionId>>,
|
|
disconnection_notify: Option<mpsc::Sender<ConnectionId>>,
|
|
stream: TcpStream,
|
|
stream: TcpStream,
|
|
) -> Result<ConnectionId, Error> {
|
|
) -> Result<ConnectionId, Error> {
|
|
- let client =
|
|
|
|
|
|
+ let conn =
|
|
Connection::new_connection(self.send_to_relayer.clone(), disconnection_notify, stream)
|
|
Connection::new_connection(self.send_to_relayer.clone(), disconnection_notify, stream)
|
|
.await?;
|
|
.await?;
|
|
- let id = client.get_conn_id();
|
|
|
|
- self.clients.write().await.insert(id, client);
|
|
|
|
|
|
+ let id = conn.get_conn_id();
|
|
|
|
+ self.connections.write().await.insert(id, conn);
|
|
|
|
|
|
Ok(id)
|
|
Ok(id)
|
|
}
|
|
}
|
|
@@ -195,7 +209,7 @@ impl<T: Storage + Send + Sync + 'static> Relayer<T> {
|
|
if let Some((client_pool, _)) = self.client_pool.as_ref() {
|
|
if let Some((client_pool, _)) = self.client_pool.as_ref() {
|
|
// pass the event to the pool of clients, so this relayer can relay
|
|
// pass the event to the pool of clients, so this relayer can relay
|
|
// their local events to the clients in the network of relayers
|
|
// their local events to the clients in the network of relayers
|
|
- let _ = client_pool.post(event.clone().into()).await;
|
|
|
|
|
|
+ let _ = client_pool.post(event.clone()).await;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Request::Request(request) => {
|
|
Request::Request(request) => {
|
|
@@ -249,7 +263,7 @@ impl<T: Storage + Send + Sync + 'static> Relayer<T> {
|
|
.await;
|
|
.await;
|
|
}
|
|
}
|
|
Request::Close(close) => {
|
|
Request::Close(close) => {
|
|
- connection.unsubscribe(&*close).await;
|
|
|
|
|
|
+ connection.unsubscribe(close).await;
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
@@ -320,7 +334,7 @@ mod test {
|
|
if prefill {
|
|
if prefill {
|
|
let events = include_str!("../tests/events.json")
|
|
let events = include_str!("../tests/events.json")
|
|
.lines()
|
|
.lines()
|
|
- .map(|line| serde_json::from_str(&line).expect("valid"))
|
|
|
|
|
|
+ .map(|line| serde_json::from_str(line).expect("valid"))
|
|
.collect::<Vec<Event>>();
|
|
.collect::<Vec<Event>>();
|
|
|
|
|
|
for event in events {
|
|
for event in events {
|
|
@@ -389,7 +403,7 @@ mod test {
|
|
]))
|
|
]))
|
|
.expect("valid object");
|
|
.expect("valid object");
|
|
let relayer = Relayer::new(Some(get_db(true).await), None).expect("valid relayer");
|
|
let relayer = Relayer::new(Some(get_db(true).await), None).expect("valid relayer");
|
|
- let (connection, mut recv) = Connection::new_for_test();
|
|
|
|
|
|
+ let (connection, mut recv) = Connection::new_local_connection();
|
|
let _ = relayer
|
|
let _ = relayer
|
|
.process_request_from_client(&connection, request)
|
|
.process_request_from_client(&connection, request)
|
|
.await;
|
|
.await;
|
|
@@ -461,6 +475,86 @@ mod test {
|
|
}
|
|
}
|
|
|
|
|
|
#[tokio::test]
|
|
#[tokio::test]
|
|
|
|
+ async fn server_listener_real_time_single_argument() {
|
|
|
|
+ let request: Request = serde_json::from_value(json!(
|
|
|
|
+ [
|
|
|
|
+ "REQ",
|
|
|
|
+ "1298169700973717",
|
|
|
|
+ {
|
|
|
|
+ "authors": ["39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb"],
|
|
|
|
+ "since":1681939304
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "#p":["39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb"],
|
|
|
|
+ "since":1681939304
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "#p":["39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb"],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "authors":["39a7d06e824c0c2523bedb93f0cef84245e4401fee03b6257a1c6dfd18b57efb"],
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ "#e":[
|
|
|
|
+ "2e72250d80e9b3fd30230b3db3ed7d22f15d266ed345c36700b01ec153c9e28a",
|
|
|
|
+ "a5e3369c43daf2675ecbce18831e5f4e07db0d4dde0ef4f5698e645e4c46eed1"
|
|
|
|
+ ],
|
|
|
|
+ }
|
|
|
|
+ ]))
|
|
|
|
+ .expect("valid object");
|
|
|
|
+ let relayer = Relayer::new(Some(get_db(false).await), None).expect("valid relayer");
|
|
|
|
+ let (connection, mut recv) = Connection::new_local_connection();
|
|
|
|
+
|
|
|
|
+ assert_eq!(relayer.total_subscribers(), 0);
|
|
|
|
+ let _ = relayer
|
|
|
|
+ .process_request_from_client(&connection, request)
|
|
|
|
+ .await;
|
|
|
|
+
|
|
|
|
+ assert_eq!(relayer.total_subscribers(), 5);
|
|
|
|
+
|
|
|
|
+ // eod
|
|
|
|
+ assert!(recv
|
|
|
|
+ .try_recv()
|
|
|
|
+ .expect("valid")
|
|
|
|
+ .as_end_of_stored_events()
|
|
|
|
+ .is_some());
|
|
|
|
+
|
|
|
|
+ // It is empty
|
|
|
|
+ assert!(recv.try_recv().is_err());
|
|
|
|
+
|
|
|
|
+ relayer
|
|
|
|
+ .process_request_from_client(&connection, get_note())
|
|
|
|
+ .await
|
|
|
|
+ .expect("process event");
|
|
|
|
+
|
|
|
|
+ sleep(Duration::from_millis(100)).await;
|
|
|
|
+
|
|
|
|
+ // It is not empty
|
|
|
|
+ let msg = recv.try_recv();
|
|
|
|
+ assert!(msg.is_ok());
|
|
|
|
+ assert_eq!(
|
|
|
|
+ msg.expect("is ok")
|
|
|
|
+ .as_event()
|
|
|
|
+ .expect("valid")
|
|
|
|
+ .subscription_id
|
|
|
|
+ .to_string(),
|
|
|
|
+ "1298169700973717".to_owned()
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // it must be deliverd at most once
|
|
|
|
+ assert!(recv.try_recv().is_err());
|
|
|
|
+ assert_eq!(relayer.total_subscribers(), 5);
|
|
|
|
+
|
|
|
|
+ // when client is dropped, the subscription is removed
|
|
|
|
+ // automatically
|
|
|
|
+ drop(connection);
|
|
|
|
+
|
|
|
|
+ sleep(Duration::from_millis(10)).await;
|
|
|
|
+
|
|
|
|
+ assert_eq!(relayer.total_subscribers(), 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #[tokio::test]
|
|
async fn server_listener_real_time() {
|
|
async fn server_listener_real_time() {
|
|
let request: Request = serde_json::from_value(json!(
|
|
let request: Request = serde_json::from_value(json!(
|
|
[
|
|
[
|
|
@@ -493,7 +587,7 @@ mod test {
|
|
]))
|
|
]))
|
|
.expect("valid object");
|
|
.expect("valid object");
|
|
let relayer = Relayer::new(Some(get_db(false).await), None).expect("valid relayer");
|
|
let relayer = Relayer::new(Some(get_db(false).await), None).expect("valid relayer");
|
|
- let (connection, mut recv) = Connection::new_for_test();
|
|
|
|
|
|
+ let (connection, mut recv) = Connection::new_local_connection();
|
|
|
|
|
|
assert_eq!(relayer.total_subscribers(), 0);
|
|
assert_eq!(relayer.total_subscribers(), 0);
|
|
let _ = relayer
|
|
let _ = relayer
|
|
@@ -557,7 +651,7 @@ mod test {
|
|
.expect("valid object");
|
|
.expect("valid object");
|
|
|
|
|
|
let relayer = Relayer::new(Some(get_db(false).await), None).expect("valid relayer");
|
|
let relayer = Relayer::new(Some(get_db(false).await), None).expect("valid relayer");
|
|
- let (connection, mut recv) = Connection::new_for_test();
|
|
|
|
|
|
+ let (connection, mut recv) = Connection::new_local_connection();
|
|
|
|
|
|
assert_eq!(relayer.total_subscribers(), 0);
|
|
assert_eq!(relayer.total_subscribers(), 0);
|
|
let _ = relayer
|
|
let _ = relayer
|
|
@@ -620,14 +714,14 @@ mod test {
|
|
.expect("valid object");
|
|
.expect("valid object");
|
|
|
|
|
|
let relayer = Relayer::new(Some(get_db(false).await), None).expect("valid relayer");
|
|
let relayer = Relayer::new(Some(get_db(false).await), None).expect("valid relayer");
|
|
- let (publisher, _) = Connection::new_for_test();
|
|
|
|
|
|
+ let (publisher, _) = Connection::new_local_connection();
|
|
|
|
|
|
let mut set1 = (0..1000)
|
|
let mut set1 = (0..1000)
|
|
- .map(|_| Connection::new_for_test())
|
|
|
|
|
|
+ .map(|_| Connection::new_local_connection())
|
|
.collect::<Vec<_>>();
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
let mut set2 = (0..100)
|
|
let mut set2 = (0..100)
|
|
- .map(|_| Connection::new_for_test())
|
|
|
|
|
|
+ .map(|_| Connection::new_local_connection())
|
|
.collect::<Vec<_>>();
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
let subscribe1 = set1
|
|
let subscribe1 = set1
|
|
@@ -712,7 +806,7 @@ mod test {
|
|
serde_json::from_value(json!(["REQ", "1298169700973717", {}])).expect("valid object");
|
|
serde_json::from_value(json!(["REQ", "1298169700973717", {}])).expect("valid object");
|
|
|
|
|
|
let relayer = Relayer::new(Some(get_db(false).await), None).expect("valid relayer");
|
|
let relayer = Relayer::new(Some(get_db(false).await), None).expect("valid relayer");
|
|
- let (connection, mut recv) = Connection::new_for_test();
|
|
|
|
|
|
+ let (connection, mut recv) = Connection::new_local_connection();
|
|
|
|
|
|
assert_eq!(relayer.total_subscribers(), 0);
|
|
assert_eq!(relayer.total_subscribers(), 0);
|
|
let _ = relayer
|
|
let _ = relayer
|