// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include class ZenCacheStore; namespace zen { class CasStore; class CidStore; class UpstreamCache; /** * Structured cache service. Imposes constraints on keys, supports blobs and * structured values * * Keys are structured as: * * {BucketId}/{KeyHash} * * Where BucketId is an alphanumeric string, and KeyHash is a 40-character hexadecimal * sequence. The hash value may be derived in any number of ways, it's up to the * application to pick an approach. * * Values may be structured or unstructured. Structured values are encoded using Unreal * Engine's compact binary encoding * * Additionally, attachments may be addressed as: * * {BucketId}/{KeyHash}/{PayloadHash} * * Where the two initial components are the same as for the main endpoint * * The storage strategy is as follows: * * - Structured values are stored in a dedicated backing store per bucket * - Unstructured values and attachments are stored in the CAS pool * */ class HttpStructuredCacheService : public zen::HttpService { public: HttpStructuredCacheService(ZenCacheStore& InCacheStore, zen::CasStore& InCasStore, zen::CidStore& InCidStore, std::unique_ptr UpstreamCache); ~HttpStructuredCacheService(); virtual const char* BaseUri() const override; virtual void HandleRequest(zen::HttpServerRequest& Request) override; void Flush(); private: struct CacheRef { std::string BucketSegment; IoHash HashKey; IoHash PayloadId; }; [[nodiscard]] bool ValidateKeyUri(zen::HttpServerRequest& Request, CacheRef& OutRef); void HandleCacheRecordRequest(zen::HttpServerRequest& Request, CacheRef& Ref); void HandleCachePayloadRequest(zen::HttpServerRequest& Request, CacheRef& Ref); void HandleCacheBucketRequest(zen::HttpServerRequest& Request, std::string_view Bucket); spdlog::logger m_Log; ZenCacheStore& m_CacheStore; zen::CasStore& m_CasStore; zen::CidStore& m_CidStore; std::unique_ptr m_UpstreamCache; }; } // namespace zen