1use crate::hanging_get::error::HangingGetServerError;
6use core::hash::Hash;
7use fuchsia_sync::Mutex;
8use std::collections::HashMap;
9use std::sync::Arc;
10
11pub struct HangingGet<S, O, F: Fn(&S, O) -> bool> {
38 inner: Arc<Mutex<HangingGetInner<S, subscriber_key::Key, O, F>>>,
39 subscriber_key_generator: subscriber_key::Generator,
42}
43
44impl<S, O, F> HangingGet<S, O, F>
45where
46 F: Fn(&S, O) -> bool,
47{
48 pub fn new(state: S, notify: F) -> Self {
55 Self {
56 inner: Arc::new(Mutex::new(HangingGetInner::new(Some(state), notify))),
57 subscriber_key_generator: subscriber_key::Generator::default(),
58 }
59 }
60
61 pub fn new_unknown_state(notify: F) -> Self {
72 Self {
73 inner: Arc::new(Mutex::new(HangingGetInner::new(None, notify))),
74 subscriber_key_generator: subscriber_key::Generator::default(),
75 }
76 }
77
78 pub fn new_publisher(&self) -> Publisher<S, O, F> {
80 Publisher { inner: self.inner.clone() }
81 }
82
83 pub fn new_subscriber(&mut self) -> Subscriber<S, O, F> {
89 Subscriber { inner: self.inner.clone(), key: self.subscriber_key_generator.next().unwrap() }
90 }
91}
92
93pub struct Subscriber<S, O, F: Fn(&S, O) -> bool> {
101 inner: Arc<Mutex<HangingGetInner<S, subscriber_key::Key, O, F>>>,
102 key: subscriber_key::Key,
103}
104
105impl<S, O, F> Subscriber<S, O, F>
106where
107 F: Fn(&S, O) -> bool,
108{
109 pub fn register(&self, observation: O) -> Result<(), HangingGetServerError> {
117 self.register2(observation).map_err(|_| HangingGetServerError::MultipleObservers)
118 }
119 pub fn register2(&self, observation: O) -> Result<(), O> {
127 self.inner.lock().subscribe(self.key, observation)
128 }
129}
130
131impl<S, O, F> Drop for Subscriber<S, O, F>
132where
133 F: Fn(&S, O) -> bool,
134{
135 fn drop(&mut self) {
136 self.inner.lock().unsubscribe(self.key);
137 }
138}
139
140pub struct Publisher<S, O, F: Fn(&S, O) -> bool> {
147 inner: Arc<Mutex<HangingGetInner<S, subscriber_key::Key, O, F>>>,
148}
149
150impl<S, O, F: Fn(&S, O) -> bool> Clone for Publisher<S, O, F> {
151 fn clone(&self) -> Self {
155 Self { inner: self.inner.clone() }
156 }
157}
158
159impl<S, O, F> Publisher<S, O, F>
160where
161 F: Fn(&S, O) -> bool,
162{
163 pub fn set(&self, state: S) {
165 self.inner.lock().set(state)
166 }
167
168 pub fn update<UpdateFn>(&self, update: UpdateFn)
178 where
179 UpdateFn: FnOnce(&mut Option<S>) -> bool,
180 {
181 self.inner.lock().update(update)
182 }
183}
184
185pub struct HangingGetInner<S, K, O, F: Fn(&S, O) -> bool> {
197 state: Option<S>,
198 notify: F,
199 observers: HashMap<K, Window<O>>,
200}
201
202impl<S, K, O, F> HangingGetInner<S, K, O, F>
203where
204 K: Eq + Hash,
205 F: Fn(&S, O) -> bool,
206{
207 fn notify_all(&mut self) {
208 for window in self.observers.values_mut() {
209 window.notify(&self.notify, self.state.as_ref().unwrap());
210 }
211 }
212
213 pub fn new(state: Option<S>, notify: F) -> Self {
217 Self { state, notify, observers: HashMap::new() }
218 }
219
220 pub fn set(&mut self, state: S) {
225 self.state = Some(state);
226 self.notify_all();
227 }
228
229 pub fn update(&mut self, state_update: impl FnOnce(&mut Option<S>) -> bool) {
232 if state_update(&mut self.state) {
233 self.notify_all();
234 }
235 }
236
237 pub fn subscribe(&mut self, key: K, observer: O) -> Result<(), O> {
249 let entry = self.observers.entry(key).or_insert_with(Window::new);
250 entry.observe(observer, &self.notify, self.state.as_ref())
251 }
252
253 pub fn unsubscribe(&mut self, key: K) {
256 drop(self.observers.remove(&key));
257 }
258}
259
260struct Window<O> {
263 dirty: bool,
264 observer: Option<O>,
265}
266
267impl<O> Window<O> {
268 pub fn new() -> Self {
270 Window { dirty: true, observer: None }
271 }
272
273 pub fn observe<S>(
279 &mut self,
280 observer: O,
281 f: impl Fn(&S, O) -> bool,
282 current_state: Option<&S>,
283 ) -> Result<(), O> {
284 if self.observer.is_some() {
285 return Err(observer);
286 }
287 self.observer = Some(observer);
288 if let Some(current_state) = current_state {
289 if self.dirty {
290 self.notify(f, current_state);
291 }
292 }
293 Ok(())
294 }
295
296 pub fn notify<S>(&mut self, f: impl Fn(&S, O) -> bool, state: &S) {
300 match self.observer.take() {
301 Some(observer) => {
302 if f(state, observer) {
303 self.dirty = false;
304 }
305 }
306 None => self.dirty = true,
307 }
308 }
309}
310
311mod subscriber_key {
313 pub struct Generator {
315 next: Key,
316 }
317
318 impl Default for Generator {
319 fn default() -> Self {
320 Self { next: Key(0) }
321 }
322 }
323
324 impl Generator {
325 pub fn next(&mut self) -> Option<Key> {
328 let key = self.next.clone();
329 if let Some(next) = self.next.0.checked_add(1) {
330 self.next.0 = next;
331 Some(key)
332 } else {
333 None
334 }
335 }
336 }
337
338 #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
340 pub struct Key(u64);
341}
342
343#[cfg(test)]
344mod tests {
345 use super::*;
346 use crate::PollExt;
347 use crate::hanging_get::test_util::TestObserver;
348 use fuchsia_async as fasync;
349 use futures::channel::oneshot;
350
351 #[test]
352 fn subscriber_key_generator_creates_unique_keys() {
353 let mut generator = subscriber_key::Generator::default();
354 let key1 = generator.next();
355 let key2 = generator.next();
356 assert!(key1 != key2);
357 }
358
359 #[test]
360 fn window_add_first_observer_notifies() {
361 let state = 0;
362 let mut window = Window::new();
363 window
364 .observe(TestObserver::expect_value(state), TestObserver::observe, Some(&state))
365 .unwrap();
366 }
367
368 #[test]
369 fn window_none_state_does_not_notify() {
370 let mut window = Window::new();
371 window
372 .observe::<i32>(TestObserver::expect_no_value(), TestObserver::observe, None)
373 .unwrap();
374 }
375
376 #[test]
377 fn window_add_second_observer_does_not_notify() {
378 let state = 0;
379 let mut window = Window::new();
380 window
381 .observe(TestObserver::expect_value(state), TestObserver::observe, Some(&state))
382 .unwrap();
383
384 window
386 .observe(TestObserver::expect_no_value(), TestObserver::observe, Some(&state))
387 .unwrap();
388 }
389
390 #[test]
391 fn window_add_second_observer_notifies_after_notify_call() {
392 let mut state = 0;
393 let mut window = Window::new();
394 window
395 .observe(TestObserver::expect_value(state), TestObserver::observe, Some(&state))
396 .unwrap();
397
398 state = 1;
399 window.notify(TestObserver::observe, &state);
400
401 window
403 .observe(TestObserver::expect_value(state), TestObserver::observe, Some(&state))
404 .unwrap();
405 }
406
407 #[test]
408 fn window_add_multiple_observers_are_notified() {
409 let mut state = 0;
410 let mut window = Window::new();
411 window
412 .observe(TestObserver::expect_value(state), TestObserver::observe, Some(&state))
413 .unwrap();
414
415 let o1 = TestObserver::expect_value(1);
417 let o2 = TestObserver::expect_no_value();
418 window.observe(o1.clone(), TestObserver::observe, Some(&state)).unwrap();
419 let result = window.observe(o2.clone(), TestObserver::observe, Some(&state));
420 assert_eq!(result, Err(o2));
421 assert!(!o1.has_value());
422 state = 1;
423 window.notify(TestObserver::observe, &state);
424 }
425
426 #[test]
427 fn window_dirty_flag_state() {
428 let state = 0;
429 let mut window = Window::new();
430 let o = TestObserver::expect_value(state);
431 window.observe(o, TestObserver::observe, Some(&state)).unwrap();
432 assert!(window.observer.is_none());
433 assert!(!window.dirty);
434 window.notify(TestObserver::observe, &state);
435 assert!(window.dirty);
436 let o = TestObserver::expect_value(state);
437 window.observe(o, TestObserver::observe, Some(&state)).unwrap();
438 assert!(!window.dirty);
439 }
440
441 #[test]
442 fn window_dirty_flag_respects_consumed_flag() {
443 let state = 0;
444 let mut window = Window::new();
445
446 let o = TestObserver::expect_value(state);
447 window.observe(o, TestObserver::observe_incomplete, Some(&state)).unwrap();
448 assert!(window.dirty);
449 }
450
451 #[test]
452 fn hanging_get_inner_subscribe() {
453 let mut hanging = HangingGetInner::new(Some(0), TestObserver::observe);
454 let o = TestObserver::expect_value(0);
455 assert!(!o.has_value());
456 hanging.subscribe(0, o.clone()).unwrap();
457 }
458
459 #[test]
460 fn hanging_get_inner_subscribe_then_set() {
461 let mut hanging = HangingGetInner::new(Some(0), TestObserver::observe);
462 let o = TestObserver::expect_value(0);
463 hanging.subscribe(0, o.clone()).unwrap();
464
465 hanging.set(1);
467 }
468
469 #[test]
470 fn hanging_get_inner_subscribe_twice_then_set() {
471 let mut hanging = HangingGetInner::new(Some(0), TestObserver::observe);
472 hanging.subscribe(0, TestObserver::expect_value(0)).unwrap();
473
474 hanging.subscribe(0, TestObserver::expect_value(1)).unwrap();
475 hanging.set(1);
476 }
477
478 #[test]
479 fn hanging_get_inner_subscribe_multiple_then_set() {
480 let mut hanging = HangingGetInner::new(Some(0), TestObserver::observe);
481 hanging.subscribe(0, TestObserver::expect_value(0)).unwrap();
482
483 let o2 = TestObserver::expect_value(1);
485 hanging.subscribe(0, o2.clone()).unwrap();
486 assert!(!o2.has_value());
487
488 let _ = hanging.subscribe(0, TestObserver::expect_no_value()).unwrap_err();
490
491 hanging.set(1);
493 }
494
495 #[test]
496 fn hanging_get_inner_subscribe_with_two_clients_then_set() {
497 let mut hanging = HangingGetInner::new(Some(0), TestObserver::observe);
498 hanging.subscribe(0, TestObserver::expect_value(0)).unwrap();
499 hanging.subscribe(0, TestObserver::expect_value(1)).unwrap();
500 hanging.subscribe(1, TestObserver::expect_value(0)).unwrap();
501 hanging.subscribe(1, TestObserver::expect_value(1)).unwrap();
502 hanging.set(1);
503 }
504
505 #[test]
506 fn hanging_get_inner_unsubscribe() {
507 let mut hanging = HangingGetInner::new(Some(0), TestObserver::observe);
508 hanging.subscribe(0, TestObserver::expect_value(0)).unwrap();
509 hanging.subscribe(0, TestObserver::expect_no_value()).unwrap();
510 hanging.unsubscribe(0);
511 hanging.set(1);
512 }
513
514 #[test]
515 fn hanging_get_inner_unsubscribe_one_of_many() {
516 let mut hanging = HangingGetInner::new(Some(0), TestObserver::observe);
517
518 hanging.subscribe(0, TestObserver::expect_value(0)).unwrap();
519 hanging.subscribe(0, TestObserver::expect_no_value()).unwrap();
520 hanging.subscribe(1, TestObserver::expect_value(0)).unwrap();
521 hanging.subscribe(1, TestObserver::expect_no_value()).unwrap();
522
523 hanging.unsubscribe(0);
525 assert!(!hanging.observers.contains_key(&0));
526 assert!(hanging.observers.contains_key(&1));
527 }
528
529 #[test]
530 fn hanging_get_inner_delayed_subscribe() {
531 let mut hanging = HangingGetInner::new(None, TestObserver::<u8>::observe);
532 let o = TestObserver::expect_no_value();
533 assert!(!o.has_value());
534 hanging.subscribe(0, o.clone()).unwrap();
535 }
536
537 #[test]
538 fn hanging_get_inner_delayed_subscribe_then_set() {
539 let mut hanging = HangingGetInner::new(None, TestObserver::observe);
540 let o = TestObserver::expect_value(1);
541 hanging.subscribe(0, o.clone()).unwrap();
542
543 hanging.set(1);
545 }
546
547 #[test]
548 fn hanging_get_inner_delayed_subscribe_twice_then_set() {
549 let mut hanging = HangingGetInner::new(None, TestObserver::observe);
550 hanging.subscribe(0, TestObserver::expect_value(1)).unwrap();
551
552 let o = TestObserver::expect_no_value();
554 let result = hanging.subscribe(0, o.clone());
555 assert_eq!(result, Err(o));
556 hanging.set(1);
557 }
558
559 #[test]
560 fn hanging_get_inner_delayed_subscribe_multiple_then_set() {
561 let mut hanging = HangingGetInner::new(None, TestObserver::observe);
562 hanging.subscribe(0, TestObserver::expect_value(1)).unwrap();
563
564 let o2 = TestObserver::expect_no_value();
567 let result = hanging.subscribe(0, o2.clone());
568 assert_eq!(result, Err(o2.clone()));
569 assert!(!o2.has_value());
570
571 let o3 = TestObserver::expect_no_value();
573 let result = hanging.subscribe(0, o3.clone());
574 assert_eq!(result, Err(o3));
575
576 hanging.set(1);
578 }
579
580 #[test]
581 fn hanging_get_inner_delayed_subscribe_with_two_clients_then_set() {
582 let mut hanging = HangingGetInner::new(None, TestObserver::observe);
583 hanging.subscribe(0, TestObserver::expect_value(1)).unwrap();
584 let o = TestObserver::expect_no_value();
585 let result = hanging.subscribe(0, o.clone());
586 assert_eq!(result, Err(o));
587 hanging.subscribe(1, TestObserver::expect_value(1)).unwrap();
588 let o2 = TestObserver::expect_no_value();
589 let result = hanging.subscribe(1, o2.clone());
590 assert_eq!(result, Err(o2));
591 hanging.set(1);
592 }
593
594 #[test]
595 fn hanging_get_inner_delayed_unsubscribe() {
596 let mut hanging = HangingGetInner::new(None, TestObserver::observe);
597 hanging.subscribe(0, TestObserver::expect_no_value()).unwrap();
598 let o = TestObserver::expect_no_value();
599 let result = hanging.subscribe(0, o.clone());
600 assert_eq!(result, Err(o));
601 hanging.unsubscribe(0);
602 hanging.set(1);
603 }
604
605 #[test]
606 fn hanging_get_inner_delayed_unsubscribe_one_of_many() {
607 let mut hanging = HangingGetInner::new(None, TestObserver::observe);
608
609 hanging.subscribe(0, TestObserver::<i32>::expect_no_value()).unwrap();
610 let o = TestObserver::expect_no_value();
611 let result = hanging.subscribe(0, o.clone());
612 assert_eq!(result, Err(o));
613 hanging.subscribe(1, TestObserver::expect_no_value()).unwrap();
614 let o2 = TestObserver::expect_no_value();
615 let result = hanging.subscribe(1, o2.clone());
616 assert_eq!(result, Err(o2));
617
618 hanging.unsubscribe(0);
620 assert!(!hanging.observers.contains_key(&0));
621 assert!(hanging.observers.contains_key(&1));
622 }
623
624 #[test]
625 fn sync_pub_sub_updates_and_observes() {
626 let mut ex = fasync::TestExecutor::new();
627 let mut broker = HangingGet::new(0i32, |s, o: oneshot::Sender<_>| {
628 o.send(s.clone()).map(|()| true).unwrap()
629 });
630 let publisher = broker.new_publisher();
631 let subscriber = broker.new_subscriber();
632
633 let (sender, mut receiver) = oneshot::channel();
635 subscriber.register(sender).unwrap();
636 let observation =
637 ex.run_until_stalled(&mut receiver).expect("received initial observation");
638 assert_eq!(observation, Ok(0));
639
640 let (sender, mut receiver) = oneshot::channel();
642 subscriber.register(sender).unwrap();
643 assert!(ex.run_until_stalled(&mut receiver).is_pending());
644
645 publisher.set(1);
646
647 let observation =
648 ex.run_until_stalled(&mut receiver).expect("received subsequent observation");
649 assert_eq!(observation, Ok(1));
650 }
651
652 #[test]
653 fn sync_pub_sub_multiple_subscribers() {
654 let mut ex = fasync::TestExecutor::new();
655 let mut broker = HangingGet::new(0i32, |s, o: oneshot::Sender<_>| {
656 o.send(s.clone()).map(|()| true).unwrap()
657 });
658 let publisher = broker.new_publisher();
659
660 let sub1 = broker.new_subscriber();
661 let sub2 = broker.new_subscriber();
662
663 let (sender, mut receiver) = oneshot::channel();
665 sub1.register(sender).unwrap();
666 let observation =
667 ex.run_until_stalled(&mut receiver).expect("received initial observation");
668 assert_eq!(observation, Ok(0));
669
670 let (sender, mut receiver) = oneshot::channel();
671 sub2.register(sender).unwrap();
672 let observation =
673 ex.run_until_stalled(&mut receiver).expect("received initial observation");
674 assert_eq!(observation, Ok(0));
675
676 let (sender, mut recv1) = oneshot::channel();
678 sub1.register(sender).unwrap();
679 assert!(ex.run_until_stalled(&mut recv1).is_pending());
680
681 let (sender, mut recv2) = oneshot::channel();
682 sub2.register(sender).unwrap();
683 assert!(ex.run_until_stalled(&mut recv2).is_pending());
684
685 publisher.set(1);
686 let obs1 =
687 ex.run_until_stalled(&mut recv1).expect("receiver 1 received subsequent observation");
688 assert_eq!(obs1, Ok(1));
689 let obs2 =
690 ex.run_until_stalled(&mut recv2).expect("receiver 2 received subsequent observation");
691 assert_eq!(obs2, Ok(1));
692 }
693
694 #[test]
695 fn sync_pub_sub_delayed_updates_and_observes() {
696 let mut ex = fasync::TestExecutor::new();
697 let mut broker = HangingGet::<i32, _, _>::new_unknown_state(|s, o: oneshot::Sender<_>| {
698 o.send(s.clone()).map(|()| true).unwrap()
699 });
700 let publisher = broker.new_publisher();
701 let subscriber = broker.new_subscriber();
702
703 let (sender, mut recv1) = oneshot::channel();
705 subscriber.register(sender).unwrap();
706 assert!(ex.run_until_stalled(&mut recv1).is_pending());
707
708 let (sender, mut receiver) = oneshot::channel();
711 assert!(subscriber.register(sender).is_err());
712 assert!(ex.run_until_stalled(&mut receiver).expect("sender closed").is_err());
713
714 publisher.set(1);
716
717 let observation =
718 ex.run_until_stalled(&mut recv1).expect("received subsequent observation");
719 assert_eq!(observation, Ok(1));
720 }
721
722 #[test]
723 fn sync_pub_sub_delayed_multiple_subscribers() {
724 let mut ex = fasync::TestExecutor::new();
725 let mut broker = HangingGet::<i32, _, _>::new_unknown_state(|s, o: oneshot::Sender<_>| {
726 o.send(s.clone()).map(|()| true).unwrap()
727 });
728 let publisher = broker.new_publisher();
729
730 let sub1 = broker.new_subscriber();
731 let sub2 = broker.new_subscriber();
732
733 let (sender, mut recv1) = oneshot::channel();
735 sub1.register(sender).unwrap();
736 assert!(ex.run_until_stalled(&mut recv1).is_pending());
737
738 let (sender, mut recv2) = oneshot::channel();
739 sub2.register(sender).unwrap();
740 assert!(ex.run_until_stalled(&mut recv2).is_pending());
741
742 let (sender, mut recv3) = oneshot::channel();
745 assert!(sub1.register(sender).is_err());
746 assert!(ex.run_until_stalled(&mut recv3).expect("sender 3 closed").is_err());
747
748 let (sender, mut recv4) = oneshot::channel();
749 assert!(sub2.register(sender).is_err());
750 assert!(ex.run_until_stalled(&mut recv4).expect("sender 4 closed").is_err());
751
752 publisher.set(1);
754 let obs1 =
755 ex.run_until_stalled(&mut recv1).expect("receiver 1 received subsequent observation");
756 assert_eq!(obs1, Ok(1));
757 let obs2 =
758 ex.run_until_stalled(&mut recv2).expect("receiver 2 received subsequent observation");
759 assert_eq!(obs2, Ok(1));
760 }
761
762 #[test]
763 fn subscriber_drop_unsubscribes() {
764 let mut broker = HangingGet::new(0i32, |s, o: oneshot::Sender<_>| {
765 o.send(s.clone()).map(|()| true).unwrap()
766 });
767 let subscriber = broker.new_subscriber();
768 assert_eq!(broker.inner.lock().observers.len(), 0);
769
770 let (sender, _receiver) = oneshot::channel();
771 subscriber.register(sender).unwrap();
772 assert_eq!(broker.inner.lock().observers.len(), 1);
773
774 drop(subscriber);
775 assert_eq!(broker.inner.lock().observers.len(), 0);
776 }
777}