Add support for SplitBlob and SpliceBlob methods - #345
Conversation
17fa168 to
5ef05b3
Compare
| func (contentAddressableStorageServer) SpliceBlob(ctx context.Context, in *remoteexecution.SpliceBlobRequest) (*remoteexecution.SpliceBlobResponse, error) { | ||
| return nil, status.Error(codes.Unimplemented, "This service does not support splicing blobs") | ||
| func (s *contentAddressableStorageServer) SpliceBlob(ctx context.Context, in *remoteexecution.SpliceBlobRequest) (*remoteexecution.SpliceBlobResponse, error) { | ||
| if s.chunkListStorage == nil { |
There was a problem hiding this comment.
Instead of doing this, why don't we require that ChunkListStorage is non-nil, and that an ErrorBlobAccess is passed in?
There was a problem hiding this comment.
We could but then the ContentAddressableStorageServer would be unable to behave differently when the ChunkListStorage is not defined. If we want the FindMissingBlobs implementation from below then we need to know when we need to verify chunk list storage and when we do not.
There was a problem hiding this comment.
Maybe good to at least add a // TODO: Require that s.chunkListStorage is non-null once we require chunking. ?
|
|
||
| // fakeBlobAccess provides a thread-safe, in-memory BlobAccess for | ||
| // testing. | ||
| type fakeBlobAccess struct { |
There was a problem hiding this comment.
Can't we just use gomock for consistency with most of the other tests in Buildbarn?
There was a problem hiding this comment.
Eh we sort of could but it becomes noisy, for some of the tests a straight up EXPECT().Return() construct flows well but for the more complicated tests such as the ones where we want to verify chunking and that files have been properly touched it becomes very noisy.
For those tests we could use .EXPECT().DoAndReturn().AnyTimes() to implement pretty much the same thing as in fakeBlobAccess already does but that would basically be the same thing as fakeBlobAccess just with lambdas instead of functions.
If you prefer that anyway I can modify the code such that it uses gomock for consistency but at least in my mind fakeBlobAccess was easier to understand.
There was a problem hiding this comment.
Do you have any input on if we want to turn fakeBlobAccess into a lambda construct with gomock for consistency or if it's fine as is?
c20835c to
e8f71eb
Compare
343d61a to
9c637a9
Compare
9c637a9 to
06da40e
Compare
| grpcClientFactory, | ||
| ) | ||
| if err != nil { | ||
| return util.StatusWrap(err, "Failed to create Chunk Map") |
There was a problem hiding this comment.
Failed to create Chunk List Storage?
| func (contentAddressableStorageServer) SpliceBlob(ctx context.Context, in *remoteexecution.SpliceBlobRequest) (*remoteexecution.SpliceBlobResponse, error) { | ||
| return nil, status.Error(codes.Unimplemented, "This service does not support splicing blobs") | ||
| func (s *contentAddressableStorageServer) SpliceBlob(ctx context.Context, in *remoteexecution.SpliceBlobRequest) (*remoteexecution.SpliceBlobResponse, error) { | ||
| if s.chunkListStorage == nil { |
There was a problem hiding this comment.
Maybe good to at least add a // TODO: Require that s.chunkListStorage is non-null once we require chunking. ?
| bigBlobDigests.Add(digest) | ||
| } | ||
| } | ||
| _, _ = s.chunkListStorage.FindMissing(ctx, bigBlobDigests.Build()) |
There was a problem hiding this comment.
Sure we don't need any error/results handling here...?
There was a problem hiding this comment.
We perform the call towards the chunk list storage in order to prevent the chunk list storage itself from being dropped from the cache if they exist. As we've yet to make the chunking mandatory semantically the blob is not missing even if it's chunk list is missing.
With regards to errors, I'm not sure how we would treat errors at this point.
| switch backend := configuration.Backend.(type) { | ||
| case *pb.BlobAccessConfiguration_ChunkListValidating: | ||
| if bac.contentAddressableStorage == nil { | ||
| return BlobAccessInfo{}, "", status.Error(codes.InvalidArgument, "Action Cache completeness checking can only be enabled if a Content Addressable Storage is configured") |
There was a problem hiding this comment.
s/Action Cache completeness checking/.../ ?
There was a problem hiding this comment.
Replaced with "Chunk list validation can only be enabled if a Content Addressable Storage is configured"
| return nil, status.Error(codes.Unimplemented, "This backend only supports upstream servers with rep max cdc support.") | ||
| } | ||
| if params.MinChunkSizeBytes < 64 { | ||
| return nil, status.Errorf(codes.Internal, "MinChunkSizeBytes was %d but a minimum of 64 is required.", params.MinChunkSizeBytes) |
There was a problem hiding this comment.
"RepMaxCDC minimum chunk size was %d bytes, but a minimum of 64 bytes is required" ?
| return nil, util.StatusWrap(err, "Unable to GetCapabilities to determine chunking parameters") | ||
| } | ||
|
|
||
| params := capabilities.GetCacheCapabilities().GetRepMaxCdcParams() |
There was a problem hiding this comment.
s/GetCacheCapabilities()/CacheCapabilities/
In the Buildbarn tree I only try to use .Get*() in cases where the parent may be nil. That way it's sort of self-documenting what can be nil or not. In this case the top-level message is always non-nil.
| } | ||
| maxMinChunkSize := (ba.maximumMessageSizeBytes + 1) / 2 | ||
| if params.MinChunkSizeBytes > uint64(maxMinChunkSize) { | ||
| return nil, status.Errorf(codes.Internal, "MinChunkSizeBytes was %d but a maximum of %d is supported with the configured maximum message size.", params.MinChunkSizeBytes, maxMinChunkSize) |
There was a problem hiding this comment.
Please make sure to remove trailing dots from the error messages.
06da40e to
0a33eb5
Compare
0a33eb5 to
190edf7
Compare
This commit adds support for the SplitBlob and SpliceBlob methods from the Remote Execution v2 (REv2) api. SplitBlob and SpliceBlob can be used to facilitate uploads and downloads of large files but a naïve implementation like this has some major drawbacks as well. The blobs must exist in both their chunked and non chunked form, which may significantly increase storage requirements for large blobs. The protocol gives no guarantee that a large blob stored in the CAS exists in its chunked form which forces you to perform a fairly heavy Split call that loads the entire large blob in order to decomposition it into its chunks. This implementation mostly exists as a stepping stone for a different implementation where Buildbarn internally manages all blobs as chunked blobs.
190edf7 to
d5f83fb
Compare
This commit adds support for the SplitBlob and SpliceBlob methods from the Remote Execution v2 (REv2) api. SplitBlob and SpliceBlob can be used to facilitate uploads and downloads of large files but a naïve implementation like this has some major drawbacks as well.
The blobs must exist in both their chunked and non chunked form, which may significantly increase storage requirements for large blobs. The protocol gives no guarantee that a large blob stored in the CAS exists in its chunked form which forces you to perform a fairly heavy Split call that loads the entire large blob in order to decomposition it into its chunks.
This implementation mostly exists as a stepping stone for a different implementation where Buildbarn internally manages all blobs as chunked blobs.