-
Notifications
You must be signed in to change notification settings - Fork 135
Replace CAS with CS and CLS #347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,10 +9,14 @@ import ( | |
| "github.com/buildbarn/bb-storage/pkg/auth" | ||
| auth_configuration "github.com/buildbarn/bb-storage/pkg/auth/configuration" | ||
| "github.com/buildbarn/bb-storage/pkg/blobstore" | ||
| "github.com/buildbarn/bb-storage/pkg/blobstore/cdc" | ||
| blobstore_configuration "github.com/buildbarn/bb-storage/pkg/blobstore/configuration" | ||
| "github.com/buildbarn/bb-storage/pkg/blobstore/grpcservers" | ||
| "github.com/buildbarn/bb-storage/pkg/builder" | ||
| "github.com/buildbarn/bb-storage/pkg/capabilities" | ||
| "github.com/buildbarn/bb-storage/pkg/clock" | ||
| "github.com/buildbarn/bb-storage/pkg/digest" | ||
| "github.com/buildbarn/bb-storage/pkg/eviction" | ||
| "github.com/buildbarn/bb-storage/pkg/global" | ||
| bb_grpc "github.com/buildbarn/bb-storage/pkg/grpc" | ||
| "github.com/buildbarn/bb-storage/pkg/program" | ||
|
|
@@ -54,34 +58,88 @@ func main() { | |
| var cacheCapabilitiesAuthorizers []auth.Authorizer | ||
|
|
||
| // Content Addressable Storage (CAS). | ||
| var contentAddressableStorageInfo *blobstore_configuration.BlobAccessInfo | ||
| var contentAddressableStorage blobstore.BlobAccess | ||
| var contentAddressableStorageKeyFormat digest.KeyFormat | ||
| var chunkListStorage blobstore.BlobAccess | ||
| if configuration.ContentAddressableStorage != nil { | ||
| info, authorizedBackend, allAuthorizers, err := newScannableBlobAccess( | ||
| casConfiguration := configuration.ContentAddressableStorage | ||
| if casConfiguration.ChunkStorage == nil { | ||
| return status.Error(codes.InvalidArgument, "The Chunk Storage is a mandatory part of the Content Addressable Storage.") | ||
| } | ||
| if casConfiguration.ChunkListStorage == nil { | ||
| return status.Error(codes.InvalidArgument, "The Chunk List Storage is a mandatory part of the Content Addressable Storage.") | ||
| } | ||
|
|
||
| var parameterCache *cdc.TTLCache[cdc.Parameters] | ||
| if casConfiguration.ContentDefinedChunkingParameterCache != nil { | ||
| parameterCacheConfiguraiton := casConfiguration.ContentDefinedChunkingParameterCache | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: Configuraiton |
||
| evictionSet, err := eviction.NewSetFromConfiguration[string](parameterCacheConfiguraiton.CacheReplacementPolicy) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| parameterCache = cdc.NewTTLCache[cdc.Parameters]( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is a cache that maps instance names to CDC parameters, right? I don't think it's correct to create such a cache globally. If you use Also in the case of centralized storage nodes I don't think it makes sense to have any caching of CDC parameters. There's nothing to cache, as the storage node would just a single configuration globally. It's only the gRPC client backend that needs a cache. Maybe better to just extend BlobAccess to have a new |
||
| clock.SystemClock, | ||
| evictionSet, | ||
| int(parameterCacheConfiguraiton.GetCacheSize()), | ||
| parameterCacheConfiguraiton.CacheDuration.AsDuration(), | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing |
||
| ) | ||
| } | ||
|
|
||
| // Create the Chunk Storage (CS). | ||
| chunkStorageInfo, chunkStorage, allAuthorizers, err := newScannableBlobAccess( | ||
| dependenciesGroup, | ||
| configuration.ContentAddressableStorage, | ||
| blobstore_configuration.NewCASBlobAccessCreator( | ||
| casConfiguration.ChunkStorage, | ||
| blobstore_configuration.NewCSBlobAccessCreator( | ||
| grpcClientFactory, | ||
| int(configuration.MaximumMessageSizeBytes), | ||
| zstdPool, | ||
| ), | ||
| grpcClientFactory, | ||
| ) | ||
| if err != nil { | ||
| return util.StatusWrap(err, "Failed to create Content Addressable Storage") | ||
| return util.StatusWrap(err, "Failed to create Content Addressable Storage: Failed to create Chunk Storage") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Failed to create Chunk Storage for Content Addressable Storage"? |
||
| } | ||
| cacheCapabilitiesProviders = append( | ||
| cacheCapabilitiesProviders, | ||
| info.BlobAccess, | ||
| chunkStorageInfo.BlobAccess, | ||
| capabilities.NewStaticProvider(&remoteexecution.ServerCapabilities{ | ||
| CacheCapabilities: &remoteexecution.CacheCapabilities{ | ||
| SupportedCompressors: configuration.SupportedCompressors, | ||
| }, | ||
| }), | ||
| ) | ||
| cacheCapabilitiesAuthorizers = append(cacheCapabilitiesAuthorizers, allAuthorizers...) | ||
| contentAddressableStorageInfo = &info | ||
| contentAddressableStorage = authorizedBackend | ||
|
|
||
| // Create the Chunk List Storage (CLS). | ||
| chunkListStorageInfo, authorizedChunkListStorage, allAuthorizers, err := newScannableBlobAccess( | ||
| dependenciesGroup, | ||
| casConfiguration.ChunkListStorage, | ||
| blobstore_configuration.NewCLSBlobAccessCreator( | ||
| &chunkStorageInfo, | ||
| grpcClientFactory, | ||
| int(configuration.MaximumMessageSizeBytes), | ||
| parameterCache, | ||
| ), | ||
| grpcClientFactory, | ||
| ) | ||
| if err != nil { | ||
| return util.StatusWrap(err, "Failed to create Content Addressable Storage: Failed to create Chunk List Storage") | ||
| } | ||
| chunkListStorage = authorizedChunkListStorage | ||
| cacheCapabilitiesProviders = append(cacheCapabilitiesProviders, chunkListStorageInfo.BlobAccess) | ||
| cacheCapabilitiesAuthorizers = append(cacheCapabilitiesAuthorizers, allAuthorizers...) | ||
|
|
||
| cdcParameterProvider := cdc.NewParameterProviderFromCapabilitiesProvider( | ||
| authorizedChunkListStorage, | ||
| int(configuration.MaximumMessageSizeBytes), | ||
| ) | ||
|
|
||
| if parameterCache != nil { | ||
| cdcParameterProvider = cdc.NewCachingParameterProvider(cdcParameterProvider, parameterCache) | ||
| } | ||
|
|
||
| contentAddressableStorage = cdc.NewCasChunkingBlobAccess(chunkStorage, authorizedChunkListStorage, cdcParameterProvider, int(configuration.MaximumMessageSizeBytes)) | ||
| contentAddressableStorageKeyFormat = chunkStorageInfo.DigestKeyFormat.Combine(chunkListStorageInfo.DigestKeyFormat) | ||
| } | ||
|
|
||
| // Action Cache (AC). | ||
|
|
@@ -91,7 +149,8 @@ func main() { | |
| dependenciesGroup, | ||
| configuration.ActionCache, | ||
| blobstore_configuration.NewACBlobAccessCreator( | ||
| contentAddressableStorageInfo, | ||
| contentAddressableStorage, | ||
| contentAddressableStorageKeyFormat, | ||
| grpcClientFactory, | ||
| int(configuration.MaximumMessageSizeBytes), | ||
| ), | ||
|
|
@@ -193,18 +252,21 @@ func main() { | |
| configuration.GrpcServers, | ||
| func(s grpc.ServiceRegistrar) { | ||
| if contentAddressableStorage != nil { | ||
| contentAddressableStorageServer := grpcservers.NewContentAddressableStorageServer( | ||
| contentAddressableStorage, | ||
| chunkListStorage, | ||
| configuration.MaximumMessageSizeBytes, | ||
| ) | ||
| remoteexecution.RegisterContentAddressableStorageServer( | ||
| s, | ||
| grpcservers.NewContentAddressableStorageServer( | ||
| contentAddressableStorage, | ||
| configuration.MaximumMessageSizeBytes, | ||
| ), | ||
| contentAddressableStorageServer, | ||
| ) | ||
| bytestream.RegisterByteStreamServer( | ||
| s, | ||
| grpcservers.NewByteStreamServer( | ||
| contentAddressableStorage, | ||
| 1<<16, | ||
| int(configuration.MaximumMessageSizeBytes), | ||
| zstdPool, | ||
| ), | ||
| ) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really a necessary requirement? I can imagine that for frontends that implement the full REv2 API it's necessary that both are provided. But for individual shards of our storage backends there is no requirement that each node provides both a CS and CLS.