Implement combined disk and HTTP cache#7512
Implement combined disk and HTTP cache#7512aherrmann wants to merge 5 commits intobazelbuild:masterfrom
Conversation
|
Additionally assigning @ola-rozenfeld because @buchgr is unavailable. |
|
CI fails on Ubuntu 14.04 with All other steps pass. I don't know, but this looks unrelated to this PR to me. |
|
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. ℹ️ Googlers: Go here for more info. |
| // Write a temporary file first, and then rename, to avoid data corruption in case of a crash. | ||
| Path temp = toPath(UUID.randomUUID().toString()); | ||
|
|
||
| try (OutputStream tempOut = temp.getOutputStream()) { |
There was a problem hiding this comment.
Using try-with-resources here caused tempOut to be closed to early occasionally leading to StreamClosed errors. Thanks @moritzkiefer-da for catching that!
|
@googlebot recheck CLA |
|
So there's good news and bad news. 👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there. 😕 The bad news is that it appears that one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that here in the pull request. Note to project maintainer: This is a terminal state, meaning the ℹ️ Googlers: Go here for more info. |
|
I agree to my commits being contributed 👍 |
buchgr
left a comment
There was a problem hiding this comment.
Hi!
thanks for the PR! I think the overall idea is sound but I think it's more future proof to implement it slightly differently. Instead of having CombinedDiskHttpBlobStore extend from DiskBlobStore you should create a generic blobstore implementation that uses composition and that can check a list of blob stores in sequence. that way the code can be used more widely, as for example we would also like to use this code with remote execution and the gRPC based --remote_cache flag.
Also please add some unit and integration tests.
|
@buchgr we can't treat the disk store too opaquely because we want to have access to the file itself to be able to stream to it and then from (or the reverse) it efficiently without intermediate buffers. so we extended it to reuse the functions getting the file names and similar. i think if we were to treat it opaquely we'd have to tweak some of the types in |
buchgr
left a comment
There was a problem hiding this comment.
fair points. overall looks good then. can add some tests please?
| @@ -0,0 +1,148 @@ | |||
| // Copyright 2017 The Bazel Authors. All rights reserved. | |||
|
|
||
| @Override | ||
| public ListenableFuture<Boolean> get(String key, OutputStream out) { | ||
| boolean use_bsDisk = super.containsKey(key); |
|
|
||
| public CombinedDiskHttpBlobStore(Path root, SimpleBlobStore bsHttp) { | ||
| super(root); | ||
| this.bsHttp = bsHttp; |
|
|
||
| import com.google.devtools.build.lib.vfs.Path; | ||
|
|
||
| /** A {@link SimpleBlobStore} implementation combining two blob stores. |
efbd7d9 to
14a8449
Compare
|
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. ℹ️ Googlers: Go here for more info. |
|
@buchgr Thanks! I've addressed your review comments.
Yes, I'm happy to add some tests. Though, I'm afraid I'll need some pointers. I tried adding two simple test cases, that check whether |
14a8449 to
9d07c7d
Compare
|
So there's good news and bad news. 👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there. 😕 The bad news is that it appears that one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that here in the pull request. Note to project maintainer: This is a terminal state, meaning the ℹ️ Googlers: Go here for more info. |
ouch :-). it's time to add some then.
Great. Yep, that's what to use for testing.
Correct. It's a bit of a mess (it's an ongoing cleanup effort). The unit tests currently mostly test error scenarios. We do have integration tests that provide a working http cache here: https://source.bazel.build/bazel/+/master:src/test/shell/bazel/remote/remote_execution_http_test.sh?q=remote_execution_http_test.sh i.e. look at Hope that helps. |
This will result in the stream being closed immediately rather then when the future finishes running which leads to StreamClosed errors.
9d07c7d to
e399b7a
Compare
|
@buchgr Thank you, yes, that helps a lot. I had been looking in the wrong place. I found some integration tests for the disk cache in |
| mkdir -p a | ||
| cat > a/BUILD <<EOF | ||
| package(default_visibility = ["//visibility:public"]) | ||
| cc_binary( |
There was a problem hiding this comment.
I know we are using cc_binary through the remote execution tests, but we are currently working towards removing it completely where not necessary and using a faster genrule (i.e one that writes hello world to some file) instead in order to speed up our tests.
There was a problem hiding this comment.
Makes sense. I've changed the test case to use a genrule instead.
| cp -f bazel-bin/a/test ${TEST_TMPDIR}/test_expected | ||
|
|
||
| # Fetch from disk cache | ||
| bazel clean --expunge |
There was a problem hiding this comment.
--expunge shouldn't be necessary here. we are trying to avoid --expunge in tests in order to make them run faster.
| || fail "Disk cache generated different result" | ||
|
|
||
| # Fetch from http cache | ||
| bazel clean --expunge |
| mkdir $cache | ||
|
|
||
| # Copy from http cache to disk cache | ||
| bazel clean --expunge |
| || fail "HTTP cache generated different result" | ||
|
|
||
| # Fetch from disk cache | ||
| bazel clean --expunge |
| bazel clean --expunge | ||
| bazel build $disk_flags //a:test &> $TEST_log \ | ||
| || fail "Failed to fetch //a:test from disk cache" | ||
| expect_log "remote cache hit" |
There was a problem hiding this comment.
"1 remote cache hit"? same below
There was a problem hiding this comment.
Yes, this is more concrete. I've changed it.
This PR adds the ability to enable disk and HTTP cache simultaneously. Specifically, if you set
Then Bazel will look for cached items in the disk cache first. If an item is not found in the disk cache, it will be looked up in the HTTP cache. If it is found there, it will be copied into the disk cache. On put, Bazel will store items in both the disk and the HTTP cache.
We tested this change on a relatively large internal project and found that a fully cached, clean build was 5-10 times faster with the mixed cache (i.e. reading from disk cache) than with a pure remote cache, depending on the remote cache location.
cc @dajmaki @francesco-da