mirror of
https://github.com/perstarkse/minne.git
synced 2026-04-26 10:48:37 +02:00
fix: harden html responses and cache chat sidebar data
Use strict template response handling and sanitized template user context, then add an in-process conversation archive cache with mutation-driven invalidation for chat sidebar renders.
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
use common::storage::types::conversation::Conversation;
|
||||
use common::storage::{db::SurrealDbClient, store::StorageManager};
|
||||
use common::utils::embedding::EmbeddingProvider;
|
||||
use common::utils::template_engine::{ProvidesTemplateEngine, TemplateEngine};
|
||||
use common::{create_template_engine, storage::db::ProvidesDb, utils::config::AppConfig};
|
||||
use retrieval_pipeline::{reranking::RerankerPool, RetrievalStrategy};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
use tokio::sync::RwLock;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::{OpenAIClientType, SessionStoreType};
|
||||
@@ -18,8 +22,17 @@ pub struct HtmlState {
|
||||
pub storage: StorageManager,
|
||||
pub reranker_pool: Option<Arc<RerankerPool>>,
|
||||
pub embedding_provider: Arc<EmbeddingProvider>,
|
||||
conversation_archive_cache: Arc<RwLock<HashMap<String, ConversationArchiveCacheEntry>>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ConversationArchiveCacheEntry {
|
||||
conversations: Vec<Conversation>,
|
||||
expires_at: Instant,
|
||||
}
|
||||
|
||||
const CONVERSATION_ARCHIVE_CACHE_TTL: Duration = Duration::from_secs(30);
|
||||
|
||||
impl HtmlState {
|
||||
pub async fn new_with_resources(
|
||||
db: Arc<SurrealDbClient>,
|
||||
@@ -44,6 +57,7 @@ impl HtmlState {
|
||||
storage,
|
||||
reranker_pool,
|
||||
embedding_provider,
|
||||
conversation_archive_cache: Arc::new(RwLock::new(HashMap::new())),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -54,6 +68,38 @@ impl HtmlState {
|
||||
.and_then(|value| value.parse().ok())
|
||||
.unwrap_or(RetrievalStrategy::Default)
|
||||
}
|
||||
|
||||
pub async fn get_cached_conversation_archive(
|
||||
&self,
|
||||
user_id: &str,
|
||||
) -> Option<Vec<Conversation>> {
|
||||
let cache = self.conversation_archive_cache.read().await;
|
||||
let entry = cache.get(user_id)?;
|
||||
if entry.expires_at <= Instant::now() {
|
||||
return None;
|
||||
}
|
||||
Some(entry.conversations.clone())
|
||||
}
|
||||
|
||||
pub async fn set_cached_conversation_archive(
|
||||
&self,
|
||||
user_id: &str,
|
||||
conversations: Vec<Conversation>,
|
||||
) {
|
||||
let mut cache = self.conversation_archive_cache.write().await;
|
||||
cache.insert(
|
||||
user_id.to_string(),
|
||||
ConversationArchiveCacheEntry {
|
||||
conversations,
|
||||
expires_at: Instant::now() + CONVERSATION_ARCHIVE_CACHE_TTL,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
pub async fn invalidate_conversation_archive_cache(&self, user_id: &str) {
|
||||
let mut cache = self.conversation_archive_cache.write().await;
|
||||
cache.remove(user_id);
|
||||
}
|
||||
}
|
||||
impl ProvidesDb for HtmlState {
|
||||
fn db(&self) -> &Arc<SurrealDbClient> {
|
||||
|
||||
Reference in New Issue
Block a user