From a199f319b73bf96d06401481e3b90aaebd6bf3b0 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Thu, 23 May 2024 07:40:19 +0100 Subject: [PATCH 1/6] pragmatically compare timestamps (as suggested by kornelski) --- src/cargo/core/compiler/fingerprint/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index f22d4a9ed97..2810d4695f6 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -1927,7 +1927,19 @@ where // if equal, files were changed just after a previous build finished. // Unfortunately this became problematic when (in #6484) cargo switch to more accurately // measuring the start time of builds. - if path_mtime <= reference_mtime { + // + // Additionally, the build can span different volumes, some which support high-precision + // file timestamps and some that don't (e.g. mounted Docker volumes). This can make + // one of the timestamps lose the nanosecond part and appear up to a second in the past. + let truncated_precision = path_mtime.nanoseconds() == 0 || reference_mtime.nanoseconds() == 0; + + let fresh = if truncated_precision { + path_mtime.unix_seconds() <= reference_mtime.unix_seconds() + } else { + path_mtime <= reference_mtime + }; + + if fresh { continue; } From 8e2581bc12283a7768de52a4bb1fa9c6a500139f Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Thu, 23 May 2024 07:53:40 +0100 Subject: [PATCH 2/6] cargo fmt --- src/cargo/core/compiler/fingerprint/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index 2810d4695f6..ebb688e58ea 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -1931,7 +1931,8 @@ where // Additionally, the build can span different volumes, some which support high-precision // file timestamps and some that don't (e.g. mounted Docker volumes). This can make // one of the timestamps lose the nanosecond part and appear up to a second in the past. - let truncated_precision = path_mtime.nanoseconds() == 0 || reference_mtime.nanoseconds() == 0; + let truncated_precision = + path_mtime.nanoseconds() == 0 || reference_mtime.nanoseconds() == 0; let fresh = if truncated_precision { path_mtime.unix_seconds() <= reference_mtime.unix_seconds() From a5daf56af7acd0b94402e90729c6a1f30b6ef7a6 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Sun, 26 May 2024 15:54:01 +0100 Subject: [PATCH 3/6] detect 1 in a million changes --- src/cargo/core/compiler/fingerprint/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index ebb688e58ea..fa282286dd6 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -1952,6 +1952,13 @@ where }); } + // If a few files in many have a .0ns mtime then still regard them as changed files. + if total_checked > 1 && truncated_precision_count == 1 { + return first; + } else if truncated_precision_count > 0 { + debug!("ignoring files that look changed due to mtime precision differences"); + } + debug!( "all paths up-to-date relative to {:?} mtime={}", reference, reference_mtime From bc2a8a3d1d0cd8c48a723ec5c2c39de99234742b Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Mon, 27 May 2024 07:33:45 +0100 Subject: [PATCH 4/6] detect 1 in a million changes --- src/cargo/core/compiler/fingerprint/mod.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index fa282286dd6..da5790191e1 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -1887,6 +1887,9 @@ where None }; + let mut truncated_precision_count : u64 = 0; + let mut total_checked: u64 = 0; + let mut first : Option = None; for path in paths { let path = path.as_ref(); @@ -1931,10 +1934,20 @@ where // Additionally, the build can span different volumes, some which support high-precision // file timestamps and some that don't (e.g. mounted Docker volumes). This can make // one of the timestamps lose the nanosecond part and appear up to a second in the past. + total_checked += 1; let truncated_precision = path_mtime.nanoseconds() == 0 || reference_mtime.nanoseconds() == 0; let fresh = if truncated_precision { + truncated_precision_count += 1; + if first.is_none() { + first = Some(StaleItem::ChangedFile { + reference: reference.to_path_buf(), + reference_mtime, + stale: path.to_path_buf(), + stale_mtime: path_mtime, + }); + } path_mtime.unix_seconds() <= reference_mtime.unix_seconds() } else { path_mtime <= reference_mtime From 97ca6b81a43cd117f5bbfda362a19b957a4105f4 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Mon, 27 May 2024 07:35:29 +0100 Subject: [PATCH 5/6] cargo fmt --- src/cargo/core/compiler/fingerprint/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index da5790191e1..077ba20eafb 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -1887,9 +1887,9 @@ where None }; - let mut truncated_precision_count : u64 = 0; + let mut truncated_precision_count: u64 = 0; let mut total_checked: u64 = 0; - let mut first : Option = None; + let mut first: Option = None; for path in paths { let path = path.as_ref(); @@ -1941,12 +1941,12 @@ where let fresh = if truncated_precision { truncated_precision_count += 1; if first.is_none() { - first = Some(StaleItem::ChangedFile { - reference: reference.to_path_buf(), - reference_mtime, - stale: path.to_path_buf(), - stale_mtime: path_mtime, - }); + first = Some(StaleItem::ChangedFile { + reference: reference.to_path_buf(), + reference_mtime, + stale: path.to_path_buf(), + stale_mtime: path_mtime, + }); } path_mtime.unix_seconds() <= reference_mtime.unix_seconds() } else { From dc7af679636dcb91cdde61f7fe7751aa2539ecb8 Mon Sep 17 00:00:00 2001 From: Squirrel Date: Mon, 27 May 2024 08:30:06 +0100 Subject: [PATCH 6/6] Update src/cargo/core/compiler/fingerprint/mod.rs --- src/cargo/core/compiler/fingerprint/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index 077ba20eafb..c42f5f1a645 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -1965,7 +1965,7 @@ where }); } - // If a few files in many have a .0ns mtime then still regard them as changed files. + // If one file in many has a .0ns mtime then still regard it as a changed file. if total_checked > 1 && truncated_precision_count == 1 { return first; } else if truncated_precision_count > 0 {