sqlite_graphrag/
memory_guard.rs1use sysinfo::{MemoryRefreshKind, RefreshKind, System};
13
14use crate::errors::AppError;
15
16pub fn check_available_memory(min_mb: u64) -> Result<u64, AppError> {
28 let sys =
29 System::new_with_specifics(RefreshKind::new().with_memory(MemoryRefreshKind::everything()));
30 let available_bytes = sys.available_memory();
31 let available_mb = available_bytes / (1024 * 1024);
32 drop(sys);
33
34 if available_mb < min_mb {
35 return Err(AppError::LowMemory {
36 available_mb,
37 required_mb: min_mb,
38 });
39 }
40
41 Ok(available_mb)
42}
43
44#[cfg(test)]
45mod testes {
46 use super::*;
47
48 #[test]
49 fn check_available_memory_com_zero_sempre_passa() {
50 let resultado = check_available_memory(0);
51 assert!(
52 resultado.is_ok(),
53 "min_mb=0 deve sempre passar, got: {resultado:?}"
54 );
55 let mb = resultado.unwrap();
56 assert!(mb > 0, "sistema deve reportar memória positiva");
57 }
58
59 #[test]
60 fn check_available_memory_com_valor_gigante_falha() {
61 let resultado = check_available_memory(u64::MAX);
62 assert!(
63 matches!(resultado, Err(AppError::LowMemory { .. })),
64 "u64::MAX MiB deve falhar com LowMemory, got: {resultado:?}"
65 );
66 }
67
68 #[test]
69 fn low_memory_error_contem_valores_corretos() {
70 match check_available_memory(u64::MAX) {
71 Err(AppError::LowMemory {
72 available_mb,
73 required_mb,
74 }) => {
75 assert_eq!(required_mb, u64::MAX);
76 assert!(available_mb < u64::MAX);
77 }
78 outro => panic!("esperado LowMemory, got: {outro:?}"),
79 }
80 }
81}