mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 09:17:30 +03:00
indexedlog: RotateLog::sync no longer errors out if latest is missing for read-only path
Summary: In rare cases (ex. some other automation runs `rm -rf`), the `latest` file can get deleted unexpectedly and cause an error. However, if `sync` is expected to do a read-only refresh to load new data, it is harmless to stay "as-is" if lastest cannot be read. Reviewed By: xavierd Differential Revision: D17763341 fbshipit-source-id: 6a493b8741b628f44709234bd69394d3b4eeb4de
This commit is contained in:
parent
80124113f3
commit
91790bc704
@ -349,17 +349,22 @@ impl RotateLog {
|
||||
if self.dir.is_none() {
|
||||
return Ok(0);
|
||||
}
|
||||
let latest = read_latest(self.dir.as_ref().unwrap())?;
|
||||
|
||||
if self.writable_log().iter_dirty().nth(0).is_none() {
|
||||
// Read-only path, no need to take directory lock.
|
||||
if latest != self.latest {
|
||||
// Latest changed. Re-load and write to the real latest Log.
|
||||
// PERF(minor): This can be smarter by avoiding reloading some logs.
|
||||
self.logs = read_logs(self.dir.as_ref().unwrap(), &self.open_options, latest)?;
|
||||
self.latest = latest;
|
||||
if let Ok(latest) = read_latest(self.dir.as_ref().unwrap()) {
|
||||
if latest != self.latest {
|
||||
// Latest changed. Re-load and write to the real latest Log.
|
||||
// PERF(minor): This can be smarter by avoiding reloading some logs.
|
||||
self.logs =
|
||||
read_logs(self.dir.as_ref().unwrap(), &self.open_options, latest)?;
|
||||
self.latest = latest;
|
||||
}
|
||||
self.writable_log().sync()?;
|
||||
} else {
|
||||
// If latest can not be read, do not error out.
|
||||
// This RotateLog can still be used to answer queries.
|
||||
}
|
||||
self.writable_log().sync()?;
|
||||
} else {
|
||||
// Read-write path. Take the directory lock.
|
||||
let dir = self.dir.clone().unwrap();
|
||||
@ -1135,6 +1140,23 @@ mod tests {
|
||||
assert!(size("2/log") < 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sync_missing_latest() {
|
||||
let dir = tempdir().unwrap();
|
||||
let opts = OpenOptions::new()
|
||||
.max_bytes_per_log(10000)
|
||||
.max_log_count(10);
|
||||
let mut rotate = opts.clone().create(true).open(&dir).unwrap();
|
||||
rotate.append(vec![b'x'; 200]).unwrap();
|
||||
rotate.sync().unwrap();
|
||||
|
||||
let mut rotate2 = opts.clone().open(&dir).unwrap();
|
||||
fs::remove_file(dir.path().join(LATEST_FILE)).unwrap();
|
||||
rotate2.sync().unwrap(); // not a failure
|
||||
rotate2.append(vec![b'y'; 200]).unwrap();
|
||||
rotate2.sync().unwrap_err(); // a failure
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repair_latest() {
|
||||
assert_eq!(guess_latest(vec![]), 0);
|
||||
|
Loading…
Reference in New Issue
Block a user