Refresh cost data from the global DB. Best-effort, non-blocking. Uses a tokio runtime because `GlobalDb` is async.
(cache: &mut CostCache)
| 381 | /// Refresh cost data from the global DB. Best-effort, non-blocking. |
| 382 | /// Uses a tokio runtime because `GlobalDb` is async. |
| 383 | fn refresh_cost_cache(cache: &mut CostCache) { |
| 384 | let future = async { |
| 385 | let Some(gdb) = crate::global_db::GlobalDb::open().await else { |
| 386 | return; |
| 387 | }; |
| 388 | |
| 389 | // Ingest any new data first |
| 390 | crate::accounting::parser::ingest(&gdb).await; |
| 391 | |
| 392 | let now_epoch = std::time::SystemTime::now() |
| 393 | .duration_since(std::time::UNIX_EPOCH) |
| 394 | .unwrap_or_default() |
| 395 | .as_secs(); |
| 396 | let today_start = now_epoch - (now_epoch % 86400); |
| 397 | let week_start = now_epoch.saturating_sub(7 * 86400); |
| 398 | |
| 399 | cache.today_cost = gdb.total_cost_since(today_start).await.unwrap_or(0.0); |
| 400 | cache.week_cost = gdb.total_cost_since(week_start).await.unwrap_or(0.0); |
| 401 | |
| 402 | let week_consumed = gdb.total_tokens_since(week_start).await.unwrap_or(0); |
| 403 | cache.tokens_saved = gdb.global_tokens_saved().await.unwrap_or(0); |
| 404 | |
| 405 | cache.efficiency_pct = if cache.tokens_saved + week_consumed > 0 { |
| 406 | (cache.tokens_saved as f64 / (cache.tokens_saved + week_consumed) as f64) * 100.0 |
| 407 | } else { |
| 408 | 0.0 |
| 409 | }; |
| 410 | |
| 411 | let models = gdb.cost_by_model_since(today_start).await; |
| 412 | if let Some((model, cost, _)) = models.first() { |
| 413 | cache.top_model.clone_from(model); |
| 414 | cache.top_model_cost = *cost; |
| 415 | } |
| 416 | }; |
| 417 | // monitor::run() is always invoked from inside #[tokio::main]'s |
| 418 | // multi-threaded runtime, so creating a new runtime would panic. |
| 419 | // Use block_in_place + the existing handle on every platform. |
| 420 | tokio::task::block_in_place(|| tokio::runtime::Handle::current().block_on(future)); |
| 421 | cache.last_refresh = std::time::Instant::now(); |
| 422 | } |
| 423 | |
| 424 | fn monitor_loop( |
| 425 | reader: &mut MmapReader, |
no test coverage detected