diff options
author | 2018-01-19 02:55:21 -0800 | |
---|---|---|
committer | 2018-01-19 02:56:58 -0800 | |
commit | 8896d2e211c57453359566c4520615c1c1f75b66 (patch) | |
tree | 05b8d52d6a254800377f1e9d479acae5584a348a /src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalValue.java | |
parent | 76eb2a4ef5747ef881f4a3d2d1e3338e4ef8913f (diff) |
Prevent broken cache entries on concurrent file changes
Local execution has an inherent race condition: if a user modifies a file while an action is executed, then it is impossible for Bazel to tell which version of the file was actually read during action execution. The file may have been modified before or after the tool has read it, or, in the worst case, the tool may have read both the original and the modified version. In addition, the file may be changed back to the original state before Bazel can check the file, so computing the digest before / after may not be sufficient.
This is a concern for both local and remote caches, although the cost of poisoning a shared remote cache is significantly higher, and is what has triggered this work.
Fixes #3360.
We solve this by keeping a reference to the FileContentsProxy, and using that to check for modificaitons before storing the cache entry. We output a warning if this check fails.
This change does not increase memory consumption; Java objects are always allocated in multiples of 8 bytes, we use compressed oops, and the FileArtifactValue currently has 12 bytes worth of fields (excl. object overhead), so adding another pointer is effectively free.
As a possible performance optimization on purely local builds, we could also consider not computing digests at all, and only use the FileContentsProxy for caching.
PiperOrigin-RevId: 182510358
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/skyframe/TransitiveTraversalValue.java')
0 files changed, 0 insertions, 0 deletions