|
@@ -1,7 +1,10 @@
|
|
|
//! Broadcaster implementation
|
|
|
use crate::{worker::Worker, Filter, Transaction};
|
|
|
use async_trait::async_trait;
|
|
|
-use std::{collections::HashMap, sync::atomic::AtomicUsize};
|
|
|
+use std::{
|
|
|
+ collections::HashMap,
|
|
|
+ sync::atomic::{AtomicBool, AtomicUsize},
|
|
|
+};
|
|
|
use tokio::sync::{
|
|
|
mpsc::{self, error::TrySendError, Receiver, Sender},
|
|
|
RwLock,
|
|
@@ -14,6 +17,7 @@ use tokio::sync::{
|
|
|
pub struct Broadcaster {
|
|
|
subscribers: RwLock<HashMap<usize, Sender<Transaction>>>,
|
|
|
subscriptions: RwLock<HashMap<Filter, Vec<usize>>>,
|
|
|
+ is_there_any_subscriber: AtomicBool,
|
|
|
index: AtomicUsize,
|
|
|
}
|
|
|
|
|
@@ -22,6 +26,7 @@ impl Default for Broadcaster {
|
|
|
Self {
|
|
|
subscribers: RwLock::new(HashMap::<usize, Sender<_>>::new()),
|
|
|
subscriptions: RwLock::new(HashMap::<Filter, Vec<_>>::new()),
|
|
|
+ is_there_any_subscriber: false.into(),
|
|
|
index: 0.into(),
|
|
|
}
|
|
|
}
|
|
@@ -44,6 +49,9 @@ impl Broadcaster {
|
|
|
|
|
|
self.subscribers.write().await.insert(sender_index, sender);
|
|
|
|
|
|
+ self.is_there_any_subscriber
|
|
|
+ .store(true, std::sync::atomic::Ordering::Release);
|
|
|
+
|
|
|
if let Some(previous_values) = listeners.get_mut(&filter) {
|
|
|
previous_values.push(sender_index);
|
|
|
} else {
|
|
@@ -58,6 +66,11 @@ impl Broadcaster {
|
|
|
impl Worker for Broadcaster {
|
|
|
type Payload = Transaction;
|
|
|
|
|
|
+ async fn process_request(&self) -> bool {
|
|
|
+ self.is_there_any_subscriber
|
|
|
+ .load(std::sync::atomic::Ordering::Acquire)
|
|
|
+ }
|
|
|
+
|
|
|
async fn handler(&self, transaction: Self::Payload) {
|
|
|
let listeners = self.subscriptions.read().await;
|
|
|
let senders = self.subscribers.read().await;
|
|
@@ -99,6 +112,14 @@ impl Worker for Broadcaster {
|
|
|
.collect::<Vec<_>>();
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ drop(listeners);
|
|
|
+ drop(senders);
|
|
|
+
|
|
|
+ if self.subscribers().await == 0 {
|
|
|
+ self.is_there_any_subscriber
|
|
|
+ .store(false, std::sync::atomic::Ordering::Release);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|