use fedimint_client_module::module::FinalClientIface;
use fedimint_client_module::sm::{DynState, ModuleNotifier};
use fedimint_core::core::ModuleInstanceId;
use fedimint_core::util::FmtCompact;
use tracing::{debug, trace};
#[derive(Clone)]
pub struct Notifier {
broadcast: tokio::sync::broadcast::Sender<DynState>,
}
impl Notifier {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
let (sender, _receiver) = tokio::sync::broadcast::channel(10_000);
Self { broadcast: sender }
}
pub fn notify(&self, state: DynState) {
let queue_len = self.broadcast.len();
trace!(?state, %queue_len, "Sending notification about state transition");
if let Err(err) = self.broadcast.send(state) {
debug!(
err = %err.fmt_compact(),
%queue_len,
receivers=self.broadcast.receiver_count(),
"Could not send state transition notification, no active receivers"
);
}
}
pub fn module_notifier<S>(
&self,
module_instance: ModuleInstanceId,
client: FinalClientIface,
) -> ModuleNotifier<S>
where
S: fedimint_client_module::sm::State,
{
ModuleNotifier::new(self.broadcast.clone(), module_instance, client)
}
pub fn sender(&self) -> NotifierSender {
NotifierSender {
sender: self.broadcast.clone(),
}
}
}
pub struct NotifierSender {
sender: tokio::sync::broadcast::Sender<DynState>,
}
impl NotifierSender {
pub fn notify(&self, state: DynState) {
let _res = self.sender.send(state);
}
}