ptth/src/watcher.rs

88 lines
1.6 KiB
Rust

// Watchers on the wall was the last good episode of Game of Thrones
use std::{
collections::*,
sync::Arc,
time::Duration,
};
use futures::channel::oneshot;
use tokio::{
sync::Mutex,
time::delay_for,
};
pub struct Watchers <T> {
pub senders: HashMap <String, oneshot::Sender <T>>,
}
impl <T> Default for Watchers <T> {
fn default () -> Self {
Self {
senders: Default::default (),
}
}
}
impl <T: 'static + Clone + Send + Sync> Watchers <T> {
pub fn add_watcher_with_id (&mut self, s: oneshot::Sender <T>, id: String) {
self.senders.insert (id, s);
}
pub fn remove_watcher (&mut self, id: &str) {
self.senders.remove (id);
}
/*
fn wake_all (&mut self, msg: T) {
let waiters = {
std::mem::take (&mut self.senders)
};
for (_id, waiter) in waiters.into_iter () {
waiter.send (msg.clone ()).ok ();
}
}
*/
pub fn wake_one (&mut self, msg: T, id: &str) -> bool {
println! ("wake_one {}", id);
if let Some (waiter) = self.senders.remove (id) {
waiter.send (msg).ok ();
true
}
else {
false
}
}
pub fn num_watchers (&self) -> usize {
self.senders.len ()
}
pub async fn long_poll (that: Arc <Mutex <Self>>, id: String) -> Option <T> {
println! ("long_poll {}", id);
let (s, r) = oneshot::channel ();
let timeout = Duration::from_secs (5);
let id_2 = id.clone ();
{
let mut that = that.lock ().await;
that.add_watcher_with_id (s, id_2)
}
tokio::spawn (async move {
delay_for (timeout).await;
let mut that = that.lock ().await;
that.remove_watcher (&id);
});
if let Ok (message) = r.await {
Some (message)
}
else {
None
}
}
}