// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include #include #include #include namespace zen { class CbObjectWriter; class CidStore; class ZenCacheStore; struct CloudCacheClientOptions; struct UpstreamCacheKey { std::string Bucket; IoHash Hash; }; struct UpstreamPayloadKey { UpstreamCacheKey CacheKey; IoHash PayloadId; }; struct UpstreamCacheRecord { ZenContentType Type = ZenContentType::kBinary; UpstreamCacheKey CacheKey; std::vector PayloadIds; }; struct UpstreamCacheOptions { std::chrono::seconds HealthCheckInterval{5}; uint32_t ThreadCount = 4; bool ReadUpstream = true; bool WriteUpstream = true; bool StatsEnabled = false; }; struct UpstreamError { int32_t ErrorCode{}; std::string Reason{}; explicit operator bool() const { return ErrorCode != 0; } }; struct GetUpstreamCacheResult { IoBuffer Value; UpstreamError Error{}; int64_t Bytes{}; double ElapsedSeconds{}; bool Success = false; }; struct PutUpstreamCacheResult { std::string Reason; int64_t Bytes{}; double ElapsedSeconds{}; bool Success = false; }; struct UpstreamEndpointHealth { std::string Reason; bool Ok = false; }; struct UpstreamEndpointStats { std::atomic_uint64_t HitCount{}; std::atomic_uint64_t MissCount{}; std::atomic_uint64_t UpCount{}; std::atomic_uint64_t ErrorCount{}; std::atomic UpBytes{}; std::atomic DownBytes{}; std::atomic SecondsUp{}; std::atomic SecondsDown{}; }; /** * The upstream endpont is responsible for handling upload/downloading of cache records. */ class UpstreamEndpoint { public: virtual ~UpstreamEndpoint() = default; virtual UpstreamEndpointHealth Initialize() = 0; virtual bool IsHealthy() const = 0; virtual UpstreamEndpointHealth CheckHealth() = 0; virtual std::string_view DisplayName() const = 0; virtual GetUpstreamCacheResult GetCacheRecord(UpstreamCacheKey CacheKey, ZenContentType Type) = 0; virtual GetUpstreamCacheResult GetCachePayload(UpstreamPayloadKey PayloadKey) = 0; virtual PutUpstreamCacheResult PutCacheRecord(const UpstreamCacheRecord& CacheRecord, IoBuffer RecordValue, std::span Payloads) = 0; virtual UpstreamEndpointStats& Stats() = 0; }; /** * Manages one or more upstream cache endpoints. */ class UpstreamCache { public: virtual ~UpstreamCache() = default; virtual bool Initialize() = 0; virtual void RegisterEndpoint(std::unique_ptr Endpoint) = 0; virtual GetUpstreamCacheResult GetCacheRecord(UpstreamCacheKey CacheKey, ZenContentType Type) = 0; virtual GetUpstreamCacheResult GetCachePayload(UpstreamPayloadKey PayloadKey) = 0; struct EnqueueResult { bool Success = false; }; virtual EnqueueResult EnqueueUpstream(UpstreamCacheRecord CacheRecord) = 0; virtual void GetStatus(CbObjectWriter& CbO) = 0; }; std::unique_ptr MakeUpstreamCache(const UpstreamCacheOptions& Options, ZenCacheStore& CacheStore, CidStore& CidStore); std::unique_ptr MakeJupiterUpstreamEndpoint(const CloudCacheClientOptions& Options); std::unique_ptr MakeZenUpstreamEndpoint(std::span Urls); } // namespace zen