use batchloader::{BatchController, BatchRules, KeySet, ValueSet};
use cooked_waker::{IntoWaker, Wake, WakeRef};
use futures::{executor, future};
use futures_timer::Delay;
use std::{
future::Future,
hash::Hash,
pin::Pin,
rc::Rc,
task::{Context, Poll},
time::Duration,
};
#[derive(Debug, Default, Copy, Clone, IntoWaker)]
struct NoOpWaker;
impl WakeRef for NoOpWaker {
fn wake_by_ref(&self) {}
}
impl Wake for NoOpWaker {
fn wake(self) {}
}
async fn put_keys_in_rc<T: Copy + Eq + Hash>(keys: KeySet<T>) -> Result<ValueSet<Rc<T>>, ()> {
Ok(keys.into_values(|key| Rc::new(*key)))
}
#[test]
fn test_simple_drop_after_resolution() {
let rules = BatchRules {
batcher: put_keys_in_rc,
window: || future::ready(()),
max_keys: None,
};
let controller = BatchController::new(&rules);
let fut1 = controller.load(1);
let fut2 = controller.load(1);
let fut3 = controller.load(1);
let fut4 = controller.load(1);
let res1 = executor::block_on(fut1).unwrap();
assert_eq!(Rc::strong_count(&res1), 2);
let res2 = executor::block_on(fut2).unwrap();
assert_eq!(Rc::strong_count(&res2), 3);
drop(fut3);
assert_eq!(Rc::strong_count(&res1), 3);
drop(fut4);
assert_eq!(Rc::strong_count(&res1), 2);
}
#[test]
fn test_drop_during_delay() {
let rules = BatchRules {
batcher: |keys: KeySet<i32>| async {
assert_eq!(keys.len(), 2);
let keys_vec: Vec<&i32> = keys.keys().collect();
assert!(keys_vec.contains(&&1));
assert!(keys_vec.contains(&&2));
if false {
Err(())
} else {
Ok(keys.into_values(|key| *key))
}
},
window: || Delay::new(Duration::from_millis(10)),
max_keys: None,
};
let controller = BatchController::new(&rules);
let waker = NoOpWaker;
let waker = waker.into_waker();
let mut ctx = Context::from_waker(&waker);
let mut fut1 = controller.load(1);
let fut11 = controller.load(1);
let fut2 = controller.load(2);
let fut3 = controller.load(3);
let poll = Pin::new(&mut fut1).poll(&mut ctx);
assert_eq!(poll, Poll::Pending);
drop(fut11);
drop(fut3);
let result: i32 = executor::block_on(fut1).unwrap();
assert_eq!(result, 1);
let result: i32 = executor::block_on(fut2).unwrap();
assert_eq!(result, 2);
}