tork_core/cache/
memory.rs1use std::time::{Duration, Instant};
4
5use moka::future::Cache as MokaCache;
6use moka::Expiry;
7
8use crate::error::Result;
9use crate::router::BoxFuture;
10
11use super::store::CacheStore;
12
13const DEFAULT_MAX_CAPACITY: u64 = 10_000;
15
16#[derive(Clone)]
18struct Entry {
19 data: Vec<u8>,
20 ttl: Option<Duration>,
21}
22
23struct PerEntryTtl;
26
27impl Expiry<String, Entry> for PerEntryTtl {
28 fn expire_after_create(
29 &self,
30 _key: &String,
31 value: &Entry,
32 _created_at: Instant,
33 ) -> Option<Duration> {
34 value.ttl
35 }
36
37 fn expire_after_update(
38 &self,
39 _key: &String,
40 value: &Entry,
41 _updated_at: Instant,
42 _duration_until_expiry: Option<Duration>,
43 ) -> Option<Duration> {
44 value.ttl
46 }
47}
48
49#[derive(Clone)]
54pub struct MemoryStore {
55 inner: MokaCache<String, Entry>,
56}
57
58impl MemoryStore {
59 pub fn new() -> Self {
61 Self::with_capacity(DEFAULT_MAX_CAPACITY)
62 }
63
64 pub fn with_capacity(max_capacity: u64) -> Self {
66 let inner = MokaCache::builder()
67 .max_capacity(max_capacity)
68 .expire_after(PerEntryTtl)
69 .build();
70 Self { inner }
71 }
72}
73
74impl Default for MemoryStore {
75 fn default() -> Self {
76 Self::new()
77 }
78}
79
80impl CacheStore for MemoryStore {
81 fn get<'a>(&'a self, key: &'a str) -> BoxFuture<'a, Result<Option<Vec<u8>>>> {
82 Box::pin(async move { Ok(self.inner.get(key).await.map(|entry| entry.data)) })
83 }
84
85 fn set(&self, key: String, value: Vec<u8>, ttl: Option<Duration>) -> BoxFuture<'_, Result<()>> {
86 Box::pin(async move {
87 self.inner.insert(key, Entry { data: value, ttl }).await;
88 Ok(())
89 })
90 }
91
92 fn delete<'a>(&'a self, key: &'a str) -> BoxFuture<'a, Result<()>> {
93 Box::pin(async move {
94 self.inner.invalidate(key).await;
95 Ok(())
96 })
97 }
98
99 fn clear(&self) -> BoxFuture<'_, Result<()>> {
100 Box::pin(async move {
101 self.inner.invalidate_all();
102 Ok(())
103 })
104 }
105}