e66008f341
This check in offers alpha support for per process metrics, you can view threads, process CPU usage over time, IO, memory, CPU time, parent process, command, uptime and journal entries. This is unfinished but all major functionality is available and I wanted to make it available to feedback and testing.
95 lines
2.7 KiB
Rust
95 lines
2.7 KiB
Rust
//! Caching for process metrics and journal entries
|
|
|
|
use std::collections::HashMap;
|
|
use std::time::{Duration, Instant};
|
|
use tokio::sync::RwLock;
|
|
|
|
use crate::types::{ProcessMetricsResponse, JournalResponse};
|
|
|
|
#[derive(Debug, Clone)]
|
|
struct CacheEntry<T> {
|
|
data: T,
|
|
cached_at: Instant,
|
|
ttl: Duration,
|
|
}
|
|
|
|
impl<T> CacheEntry<T> {
|
|
fn is_expired(&self) -> bool {
|
|
self.cached_at.elapsed() > self.ttl
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct ProcessCache {
|
|
process_metrics: RwLock<HashMap<u32, CacheEntry<ProcessMetricsResponse>>>,
|
|
journal_entries: RwLock<HashMap<u32, CacheEntry<JournalResponse>>>,
|
|
}
|
|
|
|
impl ProcessCache {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
process_metrics: RwLock::new(HashMap::new()),
|
|
journal_entries: RwLock::new(HashMap::new()),
|
|
}
|
|
}
|
|
|
|
/// Get cached process metrics if available and not expired (250ms TTL)
|
|
pub async fn get_process_metrics(&self, pid: u32) -> Option<ProcessMetricsResponse> {
|
|
let cache = self.process_metrics.read().await;
|
|
if let Some(entry) = cache.get(&pid) {
|
|
if !entry.is_expired() {
|
|
return Some(entry.data.clone());
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
/// Cache process metrics with 250ms TTL
|
|
pub async fn set_process_metrics(&self, pid: u32, data: ProcessMetricsResponse) {
|
|
let mut cache = self.process_metrics.write().await;
|
|
cache.insert(pid, CacheEntry {
|
|
data,
|
|
cached_at: Instant::now(),
|
|
ttl: Duration::from_millis(250),
|
|
});
|
|
}
|
|
|
|
/// Get cached journal entries if available and not expired (1s TTL)
|
|
pub async fn get_journal_entries(&self, pid: u32) -> Option<JournalResponse> {
|
|
let cache = self.journal_entries.read().await;
|
|
if let Some(entry) = cache.get(&pid) {
|
|
if !entry.is_expired() {
|
|
return Some(entry.data.clone());
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
/// Cache journal entries with 1s TTL
|
|
pub async fn set_journal_entries(&self, pid: u32, data: JournalResponse) {
|
|
let mut cache = self.journal_entries.write().await;
|
|
cache.insert(pid, CacheEntry {
|
|
data,
|
|
cached_at: Instant::now(),
|
|
ttl: Duration::from_secs(1),
|
|
});
|
|
}
|
|
|
|
/// Clean up expired entries periodically
|
|
pub async fn cleanup_expired(&self) {
|
|
{
|
|
let mut cache = self.process_metrics.write().await;
|
|
cache.retain(|_, entry| !entry.is_expired());
|
|
}
|
|
{
|
|
let mut cache = self.journal_entries.write().await;
|
|
cache.retain(|_, entry| !entry.is_expired());
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for ProcessCache {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
} |