Skip to content

Commit 89bac4a

Browse files
committed
Reapply "Fix disk cache failures on concurrent read-write access on Windows"
This reverts commit ac743a4.
1 parent 9dbc02a commit 89bac4a

File tree

4 files changed

+34
-3
lines changed

4 files changed

+34
-3
lines changed

src/main/java/com/google/devtools/build/lib/bazel/repository/cache/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ java_library(
2323
deps = [
2424
"//src/main/java/com/google/devtools/build/lib/server:idle_task",
2525
"//src/main/java/com/google/devtools/build/lib/util:file_system_lock",
26+
"//src/main/java/com/google/devtools/build/lib/util:os",
2627
"//src/main/java/com/google/devtools/build/lib/vfs",
2728
"//third_party:guava",
2829
"//third_party:jsr305",

src/main/java/com/google/devtools/build/lib/bazel/repository/cache/DownloadCache.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.google.common.hash.HashFunction;
2222
import com.google.common.hash.Hasher;
2323
import com.google.common.io.BaseEncoding;
24+
import com.google.devtools.build.lib.util.OS;
2425
import com.google.devtools.build.lib.vfs.DigestHashFunction;
2526
import com.google.devtools.build.lib.vfs.FileAccessException;
2627
import com.google.devtools.build.lib.vfs.FileSystemUtils;
@@ -251,7 +252,7 @@ private void storeCacheValue(
251252
// that another thread won the race to place the file in the cache. As the exception is rather
252253
// generic and could result from other failure types, we rethrow the exception if the cache
253254
// entry hasn't been created.
254-
if (!cacheValue.exists()) {
255+
if (OS.getCurrent() != OS.WINDOWS || !cacheValue.exists()) {
255256
throw e;
256257
}
257258
}

src/main/java/com/google/devtools/build/lib/remote/disk/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ java_library(
2424
"//src/main/java/com/google/devtools/build/lib/remote/util:digest_utils",
2525
"//src/main/java/com/google/devtools/build/lib/server:idle_task",
2626
"//src/main/java/com/google/devtools/build/lib/util:file_system_lock",
27+
"//src/main/java/com/google/devtools/build/lib/util:os",
2728
"//src/main/java/com/google/devtools/build/lib/vfs",
2829
"//third_party:flogger",
2930
"//third_party:guava",

src/main/java/com/google/devtools/build/lib/remote/disk/DiskCacheClient.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import com.google.devtools.build.lib.remote.util.DigestOutputStream;
3636
import com.google.devtools.build.lib.remote.util.DigestUtil;
3737
import com.google.devtools.build.lib.remote.util.Utils;
38+
import com.google.devtools.build.lib.util.OS;
39+
import com.google.devtools.build.lib.vfs.FileAccessException;
3840
import com.google.devtools.build.lib.vfs.Path;
3941
import com.google.protobuf.ByteString;
4042
import com.google.protobuf.ExtensionRegistryLite;
@@ -138,7 +140,20 @@ public void captureFile(Path src, Digest digest, Store store) throws IOException
138140
}
139141

140142
target.getParentDirectory().createDirectoryAndParents();
141-
src.renameTo(target);
143+
try {
144+
src.renameTo(target);
145+
} catch (FileAccessException e) {
146+
// On Windows, atomically replacing a file that is currently opened (e.g. due to a
147+
// concurrent get on the cache) results in renameTo throwing this exception, which wraps an
148+
// AccessDeniedException. This case is benign since if the target path already exists, we
149+
// know that another thread won the race to place the file in the cache. As the exception is
150+
// rather generic and could result from other failure types, we rethrow the exception if the
151+
// cache entry hasn't been created.
152+
if (OS.getCurrent() != OS.WINDOWS || !target.exists()) {
153+
throw e;
154+
}
155+
src.delete();
156+
}
142157
}
143158

144159
private ListenableFuture<Void> download(Digest digest, OutputStream out, Store store) {
@@ -327,7 +342,20 @@ public void saveFile(Digest digest, Store store, InputStream in) throws IOExcept
327342
}
328343
}
329344
path.getParentDirectory().createDirectoryAndParents();
330-
temp.renameTo(path);
345+
try {
346+
temp.renameTo(path);
347+
} catch (FileAccessException e) {
348+
// On Windows, atomically replacing a file that is currently opened (e.g. due to a
349+
// concurrent get on the cache) results in renameTo throwing this exception, which wraps an
350+
// AccessDeniedException. This case is benign since if the target path already exists, we
351+
// know that another thread won the race to place the file in the cache. As the exception is
352+
// rather generic and could result from other failure types, we rethrow the exception if the
353+
// cache entry hasn't been created.
354+
if (OS.getCurrent() != OS.WINDOWS || !path.exists()) {
355+
throw e;
356+
}
357+
temp.delete();
358+
}
331359
} catch (IOException e) {
332360
try {
333361
temp.delete();

0 commit comments

Comments
 (0)