(&self, path: PathBuf)
| 400 | } |
| 401 | |
| 402 | fn handle_on_cache_update(&self, path: PathBuf) { |
| 403 | trace!("handle_on_cache_update() for path: {}", path.display()); |
| 404 | |
| 405 | // ---------------------- step 1: create .stats file |
| 406 | |
| 407 | // construct .stats file path |
| 408 | let filename = path |
| 409 | .file_name() |
| 410 | .expect("Expected valid cache file name") |
| 411 | .to_str() |
| 412 | .expect("Expected valid cache file name"); |
| 413 | let stats_path = path.with_file_name(format!("{filename}.stats")); |
| 414 | |
| 415 | // create and write stats file |
| 416 | let mut stats = ModuleCacheStatistics::default(&self.cache_config); |
| 417 | stats.usages += 1; |
| 418 | write_stats_file(&stats_path, &stats); |
| 419 | |
| 420 | // ---------------------- step 2: perform cleanup task if needed |
| 421 | |
| 422 | // acquire lock for cleanup task |
| 423 | // Lock is a proof of recent cleanup task, so we don't want to delete them. |
| 424 | // Expired locks will be deleted by the cleanup task. |
| 425 | let cleanup_file = self.directory().join(".cleanup"); // some non existing marker file |
| 426 | if acquire_task_fs_lock( |
| 427 | &cleanup_file, |
| 428 | self.cache_config.cleanup_interval(), |
| 429 | self.cache_config |
| 430 | .allowed_clock_drift_for_files_from_future(), |
| 431 | ) |
| 432 | .is_none() |
| 433 | { |
| 434 | return; |
| 435 | } |
| 436 | |
| 437 | trace!("Trying to clean up cache"); |
| 438 | |
| 439 | let mut cache_index = self.list_cache_contents(); |
| 440 | let future_tolerance = SystemTime::now() |
| 441 | .checked_add( |
| 442 | self.cache_config |
| 443 | .allowed_clock_drift_for_files_from_future(), |
| 444 | ) |
| 445 | .expect("Brace your cache, the next Big Bang is coming (time overflow)"); |
| 446 | cache_index.sort_unstable_by(|lhs, rhs| { |
| 447 | // sort by age |
| 448 | use CacheEntry::*; |
| 449 | match (lhs, rhs) { |
| 450 | (Recognized { mtime: lhs_mt, .. }, Recognized { mtime: rhs_mt, .. }) => { |
| 451 | match (*lhs_mt > future_tolerance, *rhs_mt > future_tolerance) { |
| 452 | // later == younger |
| 453 | (false, false) => rhs_mt.cmp(lhs_mt), |
| 454 | // files from far future are treated as oldest recognized files |
| 455 | // we want to delete them, so the cache keeps track of recent files |
| 456 | // however, we don't delete them uncodintionally, |
| 457 | // because .stats file can be overwritten with a meaningful mtime |
| 458 | (true, false) => cmp::Ordering::Greater, |
| 459 | (false, true) => cmp::Ordering::Less, |
no test coverage detected