langfuse/prompts/
cache.rs1use std::time::{Duration, Instant};
4
5use dashmap::DashMap;
6
7use crate::prompts::chat::ChatPromptClient;
8use crate::prompts::text::TextPromptClient;
9
10struct CacheEntry<T> {
12 value: T,
13 inserted_at: Instant,
14 ttl: Duration,
15}
16
17impl<T> CacheEntry<T> {
18 fn is_expired(&self) -> bool {
19 self.inserted_at.elapsed() >= self.ttl
20 }
21}
22
23pub struct PromptCache {
28 text_entries: DashMap<String, CacheEntry<TextPromptClient>>,
29 chat_entries: DashMap<String, CacheEntry<ChatPromptClient>>,
30 default_ttl: Duration,
31}
32
33impl PromptCache {
34 pub fn new(default_ttl: Duration) -> Self {
36 Self {
37 text_entries: DashMap::new(),
38 chat_entries: DashMap::new(),
39 default_ttl,
40 }
41 }
42
43 pub fn get_text(&self, key: &str) -> Option<TextPromptClient> {
49 let entry = self.text_entries.get(key)?;
50 if entry.is_expired() {
51 drop(entry);
52 self.text_entries.remove(key);
53 return None;
54 }
55 Some(entry.value.clone())
56 }
57
58 pub fn put_text(&self, key: &str, prompt: TextPromptClient) {
60 self.text_entries.insert(
61 key.to_owned(),
62 CacheEntry {
63 value: prompt,
64 inserted_at: Instant::now(),
65 ttl: self.default_ttl,
66 },
67 );
68 }
69
70 pub fn get_text_expired(&self, key: &str) -> Option<TextPromptClient> {
75 self.text_entries.get(key).map(|entry| entry.value.clone())
76 }
77
78 pub fn get_chat(&self, key: &str) -> Option<ChatPromptClient> {
82 let entry = self.chat_entries.get(key)?;
83 if entry.is_expired() {
84 drop(entry);
85 self.chat_entries.remove(key);
86 return None;
87 }
88 Some(entry.value.clone())
89 }
90
91 pub fn put_chat(&self, key: &str, prompt: ChatPromptClient) {
93 self.chat_entries.insert(
94 key.to_owned(),
95 CacheEntry {
96 value: prompt,
97 inserted_at: Instant::now(),
98 ttl: self.default_ttl,
99 },
100 );
101 }
102
103 pub fn get_chat_expired(&self, key: &str) -> Option<ChatPromptClient> {
108 self.chat_entries.get(key).map(|entry| entry.value.clone())
109 }
110
111 pub fn clear(&self) {
115 self.text_entries.clear();
116 self.chat_entries.clear();
117 }
118
119 pub fn invalidate_by_prefix(&self, prefix: &str) {
124 self.text_entries.retain(|k, _| !k.starts_with(prefix));
125 self.chat_entries.retain(|k, _| !k.starts_with(prefix));
126 }
127}