Skip to content

Commit 783f22b

Browse files
committed
Thread through last update time to index cache
Removed in the previous commit this now adds dedicated tracking for the last update.
1 parent 5217280 commit 783f22b

File tree

5 files changed

+53
-32
lines changed

5 files changed

+53
-32
lines changed

src/cargo/sources/registry/index.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,7 @@ impl<'cfg> RegistryIndex<'cfg> {
316316
// let root = self.config.assert_package_cache_locked(&self.path);
317317
let root = load.assert_index_locked(&self.path);
318318
let cache_root = root.join(".cache");
319-
320-
// TODO: comment
321-
let lock_mtime = None;
322-
// let lock_mtime = lock
323-
// .as_ref()
324-
// .and_then(|l| l.file().metadata().ok())
325-
// .map(|t| FileTime::from_last_modification_time(&t));
326-
319+
let last_index_update = load.last_modified();;
327320

328321
// See module comment in `registry/mod.rs` for why this is structured
329322
// the way it is.
@@ -345,7 +338,7 @@ impl<'cfg> RegistryIndex<'cfg> {
345338
// along the way produce helpful "did you mean?" suggestions.
346339
for path in UncanonicalizedIter::new(&raw_path).take(1024) {
347340
let summaries = Summaries::parse(
348-
lock_mtime,
341+
last_index_update,
349342
&root,
350343
&cache_root,
351344
path.as_ref(),
@@ -465,7 +458,7 @@ impl Summaries {
465458
/// for `relative` from the underlying index (aka typically libgit2 with
466459
/// crates.io) and then parse everything in there.
467460
///
468-
/// * `lock_mtime` - this is a file modification time where if any cache
461+
/// * `last_index_update` - this is a file modification time where if any cache
469462
/// file is older than this the cache should be considered out of date and
470463
/// needs to be rebuilt.
471464
/// * `root` - this is the root argument passed to `load`
@@ -478,7 +471,7 @@ impl Summaries {
478471
/// * `load` - the actual index implementation which may be very slow to
479472
/// call. We avoid this if we can.
480473
pub fn parse(
481-
lock_mtime: Option<FileTime>,
474+
last_index_update: Option<FileTime>,
482475
root: &Path,
483476
cache_root: &Path,
484477
relative: &Path,
@@ -490,12 +483,12 @@ impl Summaries {
490483
// of reasons, but consider all of them non-fatal and just log their
491484
// occurrence in case anyone is debugging anything.
492485
let cache_path = cache_root.join(relative);
493-
if let Some(lock_mtime) = lock_mtime {
486+
if let Some(last_index_update) = last_index_update {
494487
match File::open(&cache_path) {
495488
Ok(file) => {
496489
let metadata = file.metadata()?;
497490
let cache_mtime = FileTime::from_last_modification_time(&metadata);
498-
if cache_mtime > lock_mtime {
491+
if cache_mtime > last_index_update {
499492
log::debug!("cache for {:?} is fresh", relative);
500493
match Summaries::parse_cache(&file, &metadata) {
501494
Ok(s) => return Ok(Some(s)),
@@ -560,7 +553,10 @@ impl Summaries {
560553
//
561554
// This is opportunistic so we ignore failure here but are sure to log
562555
// something in case of error.
563-
if fs::create_dir_all(cache_path.parent().unwrap()).is_ok() {
556+
//
557+
// Note that we also skip this when `last_index_update` is `None` because it
558+
// means we can't handle the cache anyway.
559+
if last_index_update.is_some() && fs::create_dir_all(cache_path.parent().unwrap()).is_ok() {
564560
let path = Filesystem::new(cache_path.clone());
565561
config.assert_package_cache_locked(&path);
566562
if let Err(e) = fs::write(cache_path, cache_bytes) {

src/cargo/sources/registry/local.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
use std::fs::File;
2-
use std::io::SeekFrom;
3-
use std::io::prelude::*;
4-
use std::path::Path;
5-
61
use crate::core::PackageId;
72
use crate::sources::registry::{MaybeLock, RegistryConfig, RegistryData};
83
use crate::util::errors::{CargoResult, CargoResultExt};
94
use crate::util::paths;
105
use crate::util::{Config, Filesystem, Sha256};
6+
use filetime::FileTime;
117
use hex;
8+
use std::fs::File;
9+
use std::io::prelude::*;
10+
use std::io::SeekFrom;
11+
use std::path::Path;
1212

1313
pub struct LocalRegistry<'cfg> {
1414
index_path: Filesystem,
@@ -43,6 +43,10 @@ impl<'cfg> RegistryData for LocalRegistry<'cfg> {
4343
path.as_path_unlocked()
4444
}
4545

46+
fn last_modified(&self) -> Option<FileTime> {
47+
None
48+
}
49+
4650
fn load(
4751
&self,
4852
root: &Path,

src/cargo/sources/registry/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ use std::fs::{File, OpenOptions};
165165
use std::io::Write;
166166
use std::path::{Path, PathBuf};
167167

168+
use filetime::FileTime;
168169
use flate2::read::GzDecoder;
169170
use log::debug;
170171
use semver::{Version, VersionReq};
@@ -371,6 +372,7 @@ pub trait RegistryData {
371372
true
372373
}
373374
fn assert_index_locked<'a>(&self, path: &'a Filesystem) -> &'a Path;
375+
fn last_modified(&self) -> Option<FileTime>;
374376
}
375377

376378
pub enum MaybeLock {

src/cargo/sources/registry/remote.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
use crate::core::{PackageId, SourceId};
2+
use crate::sources::git;
3+
use crate::sources::registry::MaybeLock;
4+
use crate::sources::registry::{RegistryConfig, RegistryData, CRATE_TEMPLATE, VERSION_TEMPLATE};
5+
use crate::util::errors::{CargoResult, CargoResultExt};
6+
use crate::util::{Config, Filesystem, Sha256};
7+
use crate::util::paths;
8+
use filetime::FileTime;
9+
use lazycell::LazyCell;
10+
use log::{debug, trace};
111
use std::cell::{Cell, Ref, RefCell};
212
use std::fmt::Write as FmtWrite;
313
use std::fs::{self, File, OpenOptions};
@@ -7,16 +17,6 @@ use std::mem;
717
use std::path::Path;
818
use std::str;
919

10-
use lazycell::LazyCell;
11-
use log::{debug, trace};
12-
13-
use crate::core::{PackageId, SourceId};
14-
use crate::sources::git;
15-
use crate::sources::registry::MaybeLock;
16-
use crate::sources::registry::{RegistryConfig, RegistryData, CRATE_TEMPLATE, VERSION_TEMPLATE};
17-
use crate::util::errors::{CargoResult, CargoResultExt};
18-
use crate::util::{Config, Filesystem, Sha256};
19-
2020
pub struct RemoteRegistry<'cfg> {
2121
index_path: Filesystem,
2222
cache_path: Filesystem,
@@ -25,6 +25,7 @@ pub struct RemoteRegistry<'cfg> {
2525
tree: RefCell<Option<git2::Tree<'static>>>,
2626
repo: LazyCell<git2::Repository>,
2727
head: Cell<Option<git2::Oid>>,
28+
last_updated: Cell<Option<FileTime>>,
2829
}
2930

3031
impl<'cfg> RemoteRegistry<'cfg> {
@@ -37,6 +38,7 @@ impl<'cfg> RemoteRegistry<'cfg> {
3738
tree: RefCell::new(None),
3839
repo: LazyCell::new(),
3940
head: Cell::new(None),
41+
last_updated: Cell::new(None),
4042
}
4143
}
4244

@@ -123,6 +125,8 @@ impl<'cfg> RemoteRegistry<'cfg> {
123125
}
124126
}
125127

128+
const LAST_UPDATED_FILE: &str = ".last-updated";
129+
126130
impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
127131
fn prepare(&self) -> CargoResult<()> {
128132
self.repo()?; // create intermediate dirs and initialize the repo
@@ -137,6 +141,16 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
137141
self.config.assert_package_cache_locked(path)
138142
}
139143

144+
fn last_modified(&self) -> Option<FileTime> {
145+
if let Some(time) = self.last_updated.get() {
146+
return Some(time);
147+
}
148+
let path = self.config.assert_package_cache_locked(&self.index_path);
149+
let mtime = paths::mtime(&path.join(LAST_UPDATED_FILE)).ok();
150+
self.last_updated.set(mtime);
151+
self.last_updated.get()
152+
}
153+
140154
fn load(
141155
&self,
142156
_root: &Path,
@@ -209,7 +223,8 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
209223
self.prepare()?;
210224
self.head.set(None);
211225
*self.tree.borrow_mut() = None;
212-
self.config.assert_package_cache_locked(&self.index_path);
226+
self.last_updated.set(None);
227+
let path = self.config.assert_package_cache_locked(&self.index_path);
213228
self.config
214229
.shell()
215230
.status("Updating", self.source_id.display_index())?;
@@ -222,6 +237,10 @@ impl<'cfg> RegistryData for RemoteRegistry<'cfg> {
222237
.chain_err(|| format!("failed to fetch `{}`", url))?;
223238
self.config.updated_sources().insert(self.source_id);
224239

240+
// Create a dummy file to record the mtime for when we updated the
241+
// index.
242+
File::create(&path.join(LAST_UPDATED_FILE))?;
243+
225244
Ok(())
226245
}
227246

tests/testsuite/concurrent.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,15 +453,15 @@ fn debug_release_ok() {
453453
let a = a.join().unwrap();
454454

455455
execs()
456-
.with_stderr(
456+
.with_stderr_contains(
457457
"\
458458
[COMPILING] foo v0.0.1 [..]
459459
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
460460
",
461461
)
462462
.run_output(&a);
463463
execs()
464-
.with_stderr(
464+
.with_stderr_contains(
465465
"\
466466
[COMPILING] foo v0.0.1 [..]
467467
[FINISHED] release [optimized] target(s) in [..]

0 commit comments

Comments
 (0)