1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use fibre_cache::CacheBuilder;
use tokio::time::{Duration, sleep};
const TINY_TTI: Duration = Duration::from_millis(200);
const JANITOR_TICK: Duration = Duration::from_millis(10);
// A sleep duration safely longer than the TTI
const SLEEP_DURATION: Duration = Duration::from_millis(400);
#[tokio::test]
async fn test_async_item_expires_after_tti() {
let cache = CacheBuilder::<&str, &str>::new()
.shards(1)
.time_to_idle(TINY_TTI)
.janitor_tick_interval(JANITOR_TICK)
.maintenance_chance(1)
.build_async()
.unwrap();
cache.insert("key", "value", 1).await;
// Wait for TTI to expire
sleep(SLEEP_DURATION).await;
// The get call will see the item is expired and return None.
assert!(
cache.fetch(&"key").await.is_none(),
"Item should expire after being idle"
);
assert_eq!(
cache.metrics().evicted_by_tti,
1,
"TTI eviction metric should be updated by janitor"
);
}
#[tokio::test]
async fn test_async_tti_is_reset_on_access() {
let cache = CacheBuilder::<&str, &str>::new()
.time_to_idle(TINY_TTI)
.janitor_tick_interval(JANITOR_TICK)
.maintenance_chance(1)
.build_async()
.unwrap();
cache.insert("key", "value", 1).await;
// Loop several times, each time sleeping for less than the TTI
// and then accessing the key to reset the idle timer.
for _ in 0..3 {
sleep(TINY_TTI / 2).await;
assert!(
cache.fetch(&"key").await.is_some(),
"Item should be present before TTI expires"
);
}
// Now, wait for the full TTI duration without access
sleep(SLEEP_DURATION).await;
// The item should finally be expired.
assert!(
cache.fetch(&"key").await.is_none(),
"Item should have expired after final idle period"
);
}