aboutsummaryrefslogtreecommitdiff
path: root/zenserver/cache/structuredcache.cpp
diff options
context:
space:
mode:
authormattpetersepic <[email protected]>2022-01-25 06:57:47 -0700
committerGitHub <[email protected]>2022-01-25 06:57:47 -0700
commitbd85a74a9d15fd676a6677fbd4d5ab4e3dcb0d42 (patch)
treee59bd4eccbc667088e74e989f2cfbbf82c6926c0 /zenserver/cache/structuredcache.cpp
parentFixed unexpected abort() call when joining an unjoinable thread (diff)
downloadzen-bd85a74a9d15fd676a6677fbd4d5ab4e3dcb0d42.tar.xz
zen-bd85a74a9d15fd676a6677fbd4d5ab4e3dcb0d42.zip
Cachepolicy (#36)
* Copy CachePolicy implementation from UE5/Release-5.0. Add backwards compatability for clients and upstreams that are using the old protocol. * Add RefPtr templated move operator and constructor, so that RefPtr<const Foo*> A = std::move(RefPtr<Foo*>()) will do a move. * Fix broken CachePolicy tests and add tests for new Save/Load. * Remove TODO comments * CachePolicy Save/Load Fixes from codereview * Fix comment to match code change. * Remove backwards compatibility for CachePolicy change. Convert policy string tokens to PascalCase. Fix tests for new policy text. Change ParseCachePolicy to assert string is non-empty and always succeed. * Fix release build: use ZEN_WITH_TESTS define
Diffstat (limited to 'zenserver/cache/structuredcache.cpp')
-rw-r--r--zenserver/cache/structuredcache.cpp297
1 files changed, 130 insertions, 167 deletions
diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp
index 5918d5178..8854ff3d1 100644
--- a/zenserver/cache/structuredcache.cpp
+++ b/zenserver/cache/structuredcache.cpp
@@ -7,6 +7,7 @@
#include <zencore/compactbinarypackage.h>
#include <zencore/compactbinaryvalidation.h>
#include <zencore/compress.h>
+#include <zencore/enumflags.h>
#include <zencore/fmtutils.h>
#include <zencore/logging.h>
#include <zencore/scopeguard.h>
@@ -42,11 +43,8 @@ using namespace std::literals;
CachePolicy
ParseCachePolicy(const HttpServerRequest::QueryParams& QueryParams)
{
- const CachePolicy QueryPolicy = zen::ParseQueryCachePolicy(QueryParams.GetValue("query"sv));
- const CachePolicy StorePolicy = zen::ParseStoreCachePolicy(QueryParams.GetValue("store"sv));
- const CachePolicy SkipPolicy = zen::ParseSkipCachePolicy(QueryParams.GetValue("skip"sv));
-
- return QueryPolicy | StorePolicy | SkipPolicy;
+ std::string_view PolicyText = QueryParams.GetValue("Policy"sv);
+ return !PolicyText.empty() ? zen::ParseCachePolicy(PolicyText) : CachePolicy::Default;
}
struct AttachmentCount
@@ -134,16 +132,15 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request)
return Request.WriteResponse(HttpResponseCode::BadRequest); // invalid URL
}
- const auto QueryParams = Request.GetQueryParams();
- CachePolicy Policy = ParseCachePolicy(QueryParams);
+ CachePolicy PolicyFromURL = ParseCachePolicy(Request.GetQueryParams());
if (Ref.PayloadId == IoHash::Zero)
{
- return HandleCacheRecordRequest(Request, Ref, Policy);
+ return HandleCacheRecordRequest(Request, Ref, PolicyFromURL);
}
else
{
- return HandleCachePayloadRequest(Request, Ref, Policy);
+ return HandleCachePayloadRequest(Request, Ref, PolicyFromURL);
}
return;
@@ -180,19 +177,19 @@ HttpStructuredCacheService::HandleCacheBucketRequest(HttpServerRequest& Request,
}
void
-HttpStructuredCacheService::HandleCacheRecordRequest(HttpServerRequest& Request, const CacheRef& Ref, CachePolicy Policy)
+HttpStructuredCacheService::HandleCacheRecordRequest(HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromURL)
{
switch (Request.RequestVerb())
{
case HttpVerb::kHead:
case HttpVerb::kGet:
{
- HandleGetCacheRecord(Request, Ref, Policy);
+ HandleGetCacheRecord(Request, Ref, PolicyFromURL);
}
break;
case HttpVerb::kPut:
- HandlePutCacheRecord(Request, Ref, Policy);
+ HandlePutCacheRecord(Request, Ref, PolicyFromURL);
break;
default:
break;
@@ -200,13 +197,12 @@ HttpStructuredCacheService::HandleCacheRecordRequest(HttpServerRequest& Request,
}
void
-HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy Policy)
+HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromURL)
{
- const ZenContentType AcceptType = Request.AcceptContentType();
- const bool SkipData = (Policy & CachePolicy::SkipData) == CachePolicy::SkipData;
- const bool SkipAttachments = (Policy & CachePolicy::SkipAttachments) == CachePolicy::SkipAttachments;
- const bool PartialOnError = (Policy & CachePolicy::PartialOnError) == CachePolicy::PartialOnError;
- const bool QueryUpstream = (Policy & CachePolicy::QueryRemote) == CachePolicy::QueryRemote;
+ const ZenContentType AcceptType = Request.AcceptContentType();
+ const bool SkipData = EnumHasAllFlags(PolicyFromURL, CachePolicy::SkipData);
+ const bool PartialRecord = EnumHasAllFlags(PolicyFromURL, CachePolicy::PartialRecord);
+ const bool QueryUpstream = EnumHasAllFlags(PolicyFromURL, CachePolicy::QueryRemote);
bool Success = false;
ZenCacheValue LocalCacheValue;
@@ -221,28 +217,18 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
uint32_t MissingCount = 0;
CbObjectView CacheRecord(LocalCacheValue.Value.Data());
- CacheRecord.IterateAttachments([this, SkipAttachments, &MissingCount, &Package](CbFieldView AttachmentHash) {
- if (SkipAttachments && MissingCount == 0)
+ CacheRecord.IterateAttachments([this, &MissingCount, &Package](CbFieldView AttachmentHash) {
+ if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash()))
{
- if (!m_CidStore.ContainsChunk(AttachmentHash.AsHash()))
- {
- MissingCount++;
- }
+ Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk))));
}
else
{
- if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash()))
- {
- Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk))));
- }
- else
- {
- MissingCount++;
- }
+ MissingCount++;
}
});
- Success = MissingCount == 0 || PartialOnError;
+ Success = MissingCount == 0 || PartialRecord;
if (Success)
{
@@ -286,7 +272,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
// Issue upstream query asynchronously in order to keep requests flowing without
// hogging I/O servicing threads with blocking work
- Request.WriteResponseAsync([this, AcceptType, SkipData, SkipAttachments, PartialOnError, Ref](HttpServerRequest& AsyncRequest) {
+ Request.WriteResponseAsync([this, AcceptType, SkipData, PartialRecord, Ref](HttpServerRequest& AsyncRequest) {
bool Success = false;
ZenCacheValue UpstreamCacheValue;
@@ -328,7 +314,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
CbObject CacheRecord = Package.GetObject();
AttachmentCount Count;
- CacheRecord.IterateAttachments([this, &Package, &Ref, &Count, SkipAttachments](CbFieldView HashView) {
+ CacheRecord.IterateAttachments([this, &Package, &Ref, &Count](CbFieldView HashView) {
if (const CbAttachment* Attachment = Package.FindAttachment(HashView.AsHash()))
{
if (CompressedBuffer Compressed = Attachment->AsCompressedBinary())
@@ -342,7 +328,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
}
else
{
- ZEN_WARN("Uncompressed payload '{}' from upstream cache record '{}/{}'",
+ ZEN_WARN("Uncompressed value '{}' from upstream cache record '{}/{}'",
HashView.AsHash(),
Ref.BucketSegment,
Ref.HashKey);
@@ -351,16 +337,13 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
}
else if (IoBuffer Chunk = m_CidStore.FindChunkByCid(HashView.AsHash()))
{
- if (!SkipAttachments)
- {
- Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk))));
- }
+ Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk))));
Count.Valid++;
}
Count.Total++;
});
- if ((Count.Valid == Count.Total) || PartialOnError)
+ if ((Count.Valid == Count.Total) || PartialRecord)
{
ZenCacheValue CacheValue;
CacheValue.Value = CacheRecord.GetBuffer().AsIoBuffer();
@@ -368,12 +351,6 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, CacheValue);
- if (SkipAttachments)
- {
- Package.Reset();
- Package.SetObject(CacheRecord);
- }
-
BinaryWriter MemStream;
Package.Save(MemStream);
@@ -427,7 +404,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
}
void
-HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy Policy)
+HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromURL)
{
IoBuffer Body = Request.ReadPayload();
@@ -436,8 +413,7 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request
return Request.WriteResponse(HttpResponseCode::BadRequest);
}
- const HttpContentType ContentType = Request.RequestContentType();
- const bool StoreUpstream = (Policy & CachePolicy::StoreRemote) == CachePolicy::StoreRemote;
+ const HttpContentType ContentType = Request.RequestContentType();
Body.SetContentType(ContentType);
@@ -446,7 +422,7 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request
ZEN_DEBUG("PUT - '{}/{}' {} '{}'", Ref.BucketSegment, Ref.HashKey, NiceBytes(Body.Size()), ToString(ContentType));
m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, {.Value = Body});
- if (StoreUpstream)
+ if (EnumHasAllFlags(PolicyFromURL, CachePolicy::StoreRemote))
{
m_UpstreamCache.EnqueueUpstream({.Type = ZenContentType::kBinary, .Key = {Ref.BucketSegment, Ref.HashKey}});
}
@@ -463,6 +439,7 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request
return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Compact binary validation failed"sv);
}
+ CachePolicy Policy = PolicyFromURL;
CbObjectView CacheRecord(Body.Data());
std::vector<IoHash> ValidAttachments;
int32_t TotalCount = 0;
@@ -489,7 +466,7 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request
const bool IsPartialRecord = TotalCount != static_cast<int32_t>(ValidAttachments.size());
- if (StoreUpstream && !IsPartialRecord)
+ if (EnumHasAllFlags(Policy, CachePolicy::StoreRemote) && !IsPartialRecord)
{
m_UpstreamCache.EnqueueUpstream(
{.Type = ZenContentType::kCbObject, .Key = {Ref.BucketSegment, Ref.HashKey}, .PayloadIds = std::move(ValidAttachments)});
@@ -506,6 +483,7 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request
ZEN_WARN("PUT - '{}/{}' '{}' FAILED, invalid package", Ref.BucketSegment, Ref.HashKey, ToString(ContentType));
return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid package"sv);
}
+ CachePolicy Policy = PolicyFromURL;
CbObject CacheRecord = Package.GetObject();
AttachmentCount Count;
@@ -570,7 +548,7 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request
const bool IsPartialRecord = Count.Valid != Count.Total;
- if (StoreUpstream && !IsPartialRecord)
+ if (EnumHasAllFlags(Policy, CachePolicy::StoreRemote) && !IsPartialRecord)
{
m_UpstreamCache.EnqueueUpstream(
{.Type = ZenContentType::kCbPackage, .Key = {Ref.BucketSegment, Ref.HashKey}, .PayloadIds = std::move(ValidAttachments)});
@@ -585,18 +563,16 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request
}
void
-HttpStructuredCacheService::HandleCachePayloadRequest(HttpServerRequest& Request, const CacheRef& Ref, CachePolicy Policy)
+HttpStructuredCacheService::HandleCachePayloadRequest(HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromURL)
{
switch (Request.RequestVerb())
{
case HttpVerb::kHead:
case HttpVerb::kGet:
- {
- HandleGetCachePayload(Request, Ref, Policy);
- }
+ HandleGetCachePayload(Request, Ref, PolicyFromURL);
break;
case HttpVerb::kPut:
- HandlePutCachePayload(Request, Ref, Policy);
+ HandlePutCachePayload(Request, Ref, PolicyFromURL);
break;
default:
break;
@@ -604,11 +580,12 @@ HttpStructuredCacheService::HandleCachePayloadRequest(HttpServerRequest& Request
}
void
-HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy Policy)
+HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromURL)
{
- IoBuffer Payload = m_CidStore.FindChunkByCid(Ref.PayloadId);
- bool InUpstreamCache = false;
- const bool QueryUpstream = !Payload && (Policy & CachePolicy::QueryRemote) == CachePolicy::QueryRemote;
+ IoBuffer Payload = m_CidStore.FindChunkByCid(Ref.PayloadId);
+ bool InUpstreamCache = false;
+ CachePolicy Policy = PolicyFromURL;
+ const bool QueryUpstream = !Payload && EnumHasAllFlags(Policy, CachePolicy::QueryRemote);
if (QueryUpstream)
{
@@ -621,7 +598,7 @@ HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Reques
}
else
{
- ZEN_WARN("got uncompressed upstream cache payload");
+ ZEN_WARN("got uncompressed upstream cache value");
}
}
}
@@ -647,7 +624,7 @@ HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Reques
m_CacheStats.UpstreamHitCount++;
}
- if ((Policy & CachePolicy::SkipData) == CachePolicy::SkipData)
+ if (EnumHasAllFlags(Policy, CachePolicy::SkipData))
{
Request.WriteResponse(HttpResponseCode::OK);
}
@@ -658,10 +635,10 @@ HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Reques
}
void
-HttpStructuredCacheService::HandlePutCachePayload(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy Policy)
+HttpStructuredCacheService::HandlePutCachePayload(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy PolicyFromURL)
{
- // Note: Individual cache payloads are not propagated upstream until a valid cache record has been stored
- ZEN_UNUSED(Policy);
+ // Note: Individual cacherecord values are not propagated upstream until a valid cache record has been stored
+ ZEN_UNUSED(PolicyFromURL);
IoBuffer Body = Request.ReadPayload();
@@ -681,7 +658,7 @@ HttpStructuredCacheService::HandlePutCachePayload(zen::HttpServerRequest& Reques
if (IoHash::FromBLAKE3(Compressed.GetRawHash()) != Ref.PayloadId)
{
- return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Payload ID does not match attachment hash"sv);
+ return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "ValueId does not match attachment hash"sv);
}
CidStore::InsertResult Result = m_CidStore.AddChunk(Compressed);
@@ -731,7 +708,7 @@ HttpStructuredCacheService::ValidateKeyUri(HttpServerRequest& Request, CacheRef&
}
else
{
- // Cache record + payload lookup
+ // Cache record + valueid lookup
HashSegment = Key.substr(BucketSplitOffset + 1, PayloadSplitOffset - BucketSplitOffset - 1);
PayloadSegment = Key.substr(PayloadSplitOffset + 1);
}
@@ -787,7 +764,7 @@ HttpStructuredCacheService::HandleRpcRequest(zen::HttpServerRequest& Request)
{
HandleRpcGetCacheRecords(AsyncRequest, RpcRequest);
}
- else if (Method == "GetCachePayloads"sv)
+ else if (Method == "GetCacheValues"sv)
{
HandleRpcGetCachePayloads(AsyncRequest, RpcRequest);
}
@@ -818,11 +795,10 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req
ZEN_ASSERT(RpcRequest["Method"sv].AsString() == "GetCacheRecords"sv);
- CacheRecordPolicy::Load(Params["Policy"sv].AsObjectView(), Policy);
+ Policy = CacheRecordPolicy::Load(Params["Policy"sv].AsObjectView());
- const bool PartialOnError = Policy.HasRecordPolicy(CachePolicy::PartialOnError);
- const bool SkipAttachments = Policy.HasRecordPolicy(CachePolicy::SkipAttachments);
- const bool QueryRemote = Policy.HasRecordPolicy(CachePolicy::QueryRemote);
+ const bool PartialRecord = EnumHasAllFlags(Policy.GetRecordPolicy(), CachePolicy::PartialRecord);
+ const bool QueryRemote = EnumHasAllFlags(Policy.GetRecordPolicy(), CachePolicy::QueryRemote);
for (CbFieldView KeyView : Params["CacheKeys"sv])
{
@@ -845,30 +821,20 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req
if (m_CacheStore.Get(Key.Bucket, Key.Hash, CacheValue))
{
CbObjectView CacheRecord(CacheValue.Value.Data());
- CacheRecord.IterateAttachments([this, SkipAttachments, &MissingCount, &RpcResponse](CbFieldView AttachmentHash) {
- if (SkipAttachments && MissingCount == 0)
+ CacheRecord.IterateAttachments([this, &MissingCount, &RpcResponse](CbFieldView AttachmentHash) {
+ if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash()))
{
- if (!m_CidStore.ContainsChunk(AttachmentHash.AsHash()))
- {
- MissingCount++;
- }
+ ZEN_ASSERT(Chunk.GetSize() > 0);
+ RpcResponse.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk))));
}
else
{
- if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash()))
- {
- ZEN_ASSERT(Chunk.GetSize() > 0);
- RpcResponse.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk))));
- }
- else
- {
- MissingCount++;
- }
+ MissingCount++;
}
});
}
- if (CacheValue.Value && (MissingCount == 0 || PartialOnError))
+ if (CacheValue.Value && (MissingCount == 0 || PartialRecord))
{
ZEN_DEBUG("HIT - '{}/{}' {} '{}' (LOCAL) {}",
Key.Bucket,
@@ -895,80 +861,76 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req
if (!UpstreamRequests.empty())
{
- const auto OnCacheRecordGetComplete =
- [this, &CacheValues, &RpcResponse, PartialOnError, SkipAttachments](CacheRecordGetCompleteParams&& Params) {
- ZEN_ASSERT(Params.KeyIndex < CacheValues.size());
+ const auto OnCacheRecordGetComplete = [this, &CacheValues, &RpcResponse, PartialRecord](CacheRecordGetCompleteParams&& Params) {
+ ZEN_ASSERT(Params.KeyIndex < CacheValues.size());
- IoBuffer CacheValue;
- AttachmentCount Count;
+ IoBuffer CacheValue;
+ AttachmentCount Count;
- if (Params.Record)
- {
- Params.Record.IterateAttachments([this, &RpcResponse, SkipAttachments, &Params, &Count](CbFieldView HashView) {
- if (const CbAttachment* Attachment = Params.Package.FindAttachment(HashView.AsHash()))
+ if (Params.Record)
+ {
+ Params.Record.IterateAttachments([this, &RpcResponse, &Params, &Count](CbFieldView HashView) {
+ if (const CbAttachment* Attachment = Params.Package.FindAttachment(HashView.AsHash()))
+ {
+ if (CompressedBuffer Compressed = Attachment->AsCompressedBinary())
{
- if (CompressedBuffer Compressed = Attachment->AsCompressedBinary())
+ auto InsertResult = m_CidStore.AddChunk(Compressed);
+ if (InsertResult.New)
{
- auto InsertResult = m_CidStore.AddChunk(Compressed);
- if (InsertResult.New)
- {
- Count.New++;
- }
- Count.Valid++;
-
- if (!SkipAttachments)
- {
- RpcResponse.AddAttachment(CbAttachment(Compressed));
- }
- }
- else
- {
- ZEN_DEBUG("Uncompressed payload '{}' from upstream cache record '{}/{}'",
- HashView.AsHash(),
- Params.Key.Bucket,
- Params.Key.Hash);
- Count.Invalid++;
+ Count.New++;
}
+ Count.Valid++;
+
+ RpcResponse.AddAttachment(CbAttachment(Compressed));
}
- else if (m_CidStore.ContainsChunk(HashView.AsHash()))
+ else
{
- Count.Valid++;
+ ZEN_DEBUG("Uncompressed value '{}' from upstream cache record '{}/{}'",
+ HashView.AsHash(),
+ Params.Key.Bucket,
+ Params.Key.Hash);
+ Count.Invalid++;
}
- Count.Total++;
- });
-
- if ((Count.Valid == Count.Total) || PartialOnError)
+ }
+ else if (m_CidStore.ContainsChunk(HashView.AsHash()))
{
- CacheValue = CbObject::Clone(Params.Record).GetBuffer().AsIoBuffer();
+ Count.Valid++;
}
- }
+ Count.Total++;
+ });
- if (CacheValue)
- {
- ZEN_DEBUG("HIT - '{}/{}' {} '{}' attachments '{}/{}/{}' (new/valid/total) (UPSTREAM)",
- Params.Key.Bucket,
- Params.Key.Hash,
- NiceBytes(CacheValue.GetSize()),
- ToString(HttpContentType::kCbPackage),
- Count.New,
- Count.Valid,
- Count.Total);
-
- CacheValue.SetContentType(ZenContentType::kCbObject);
-
- CacheValues[Params.KeyIndex] = CacheValue;
- m_CacheStore.Put(Params.Key.Bucket, Params.Key.Hash, {.Value = CacheValue});
-
- m_CacheStats.HitCount++;
- m_CacheStats.UpstreamHitCount++;
- }
- else
+ if ((Count.Valid == Count.Total) || PartialRecord)
{
- const bool IsPartial = Count.Valid != Count.Total;
- ZEN_DEBUG("MISS - '{}/{}' {}", Params.Key.Bucket, Params.Key.Hash, IsPartial ? "(partial)"sv : ""sv);
- m_CacheStats.MissCount++;
+ CacheValue = CbObject::Clone(Params.Record).GetBuffer().AsIoBuffer();
}
- };
+ }
+
+ if (CacheValue)
+ {
+ ZEN_DEBUG("HIT - '{}/{}' {} '{}' attachments '{}/{}/{}' (new/valid/total) (UPSTREAM)",
+ Params.Key.Bucket,
+ Params.Key.Hash,
+ NiceBytes(CacheValue.GetSize()),
+ ToString(HttpContentType::kCbPackage),
+ Count.New,
+ Count.Valid,
+ Count.Total);
+
+ CacheValue.SetContentType(ZenContentType::kCbObject);
+
+ CacheValues[Params.KeyIndex] = CacheValue;
+ m_CacheStore.Put(Params.Key.Bucket, Params.Key.Hash, {.Value = CacheValue});
+
+ m_CacheStats.HitCount++;
+ m_CacheStats.UpstreamHitCount++;
+ }
+ else
+ {
+ const bool IsPartial = Count.Valid != Count.Total;
+ ZEN_DEBUG("MISS - '{}/{}' {}", Params.Key.Bucket, Params.Key.Hash, IsPartial ? "(partial)"sv : ""sv);
+ m_CacheStats.MissCount++;
+ }
+ };
m_UpstreamCache.GetCacheRecords(CacheKeys, UpstreamRequests, Policy, std::move(OnCacheRecordGetComplete));
}
@@ -1005,7 +967,7 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re
{
ZEN_TRACE_CPU("Z$::RpcGetCachePayloads");
- ZEN_ASSERT(RpcRequest["Method"sv].AsString() == "GetCachePayloads"sv);
+ ZEN_ASSERT(RpcRequest["Method"sv].AsString() == "GetCacheValues"sv);
std::vector<CacheChunkRequest> ChunkRequests;
std::vector<size_t> UpstreamRequests;
@@ -1014,19 +976,20 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re
for (CbFieldView RequestView : Params["ChunkRequests"sv])
{
- CbObjectView RequestObject = RequestView.AsObjectView();
- CbObjectView KeyObject = RequestObject["Key"sv].AsObjectView();
- const CacheKey Key = CacheKey::Create(KeyObject["Bucket"sv].AsString(), KeyObject["Hash"sv].AsHash());
- const IoHash ChunkId = RequestObject["ChunkId"sv].AsHash();
- const Oid PayloadId = RequestObject["PayloadId"sv].AsObjectId();
- const uint64_t RawOffset = RequestObject["RawOffset"sv].AsUInt64();
- const uint64_t RawSize = RequestObject["RawSize"sv].AsUInt64();
- const uint32_t ChunkPolicy = RequestObject["Policy"sv].AsUInt32();
+ CbObjectView RequestObject = RequestView.AsObjectView();
+ CbObjectView KeyObject = RequestObject["Key"sv].AsObjectView();
+ const CacheKey Key = CacheKey::Create(KeyObject["Bucket"sv].AsString(), KeyObject["Hash"sv].AsHash());
+ const IoHash ChunkId = RequestObject["ChunkId"sv].AsHash();
+ const Oid PayloadId = RequestObject["ValueId"sv].AsObjectId();
+ const uint64_t RawOffset = RequestObject["RawOffset"sv].AsUInt64();
+ const uint64_t RawSize = RequestObject["RawSize"sv].AsUInt64();
+ std::string_view PolicyText = RequestObject["Policy"sv].AsString();
+ const CachePolicy ChunkPolicy = !PolicyText.empty() ? ParseCachePolicy(PolicyText) : CachePolicy::Default;
// Note we could use emplace_back here but [Apple] LLVM-12's C++ library
// can't infer a constructor like other platforms (or can't handle an
// initializer list like others do).
- ChunkRequests.push_back({Key, ChunkId, PayloadId, RawOffset, RawSize, static_cast<CachePolicy>(ChunkPolicy)});
+ ChunkRequests.push_back({Key, ChunkId, PayloadId, RawOffset, RawSize, ChunkPolicy});
}
if (ChunkRequests.empty())
@@ -1036,13 +999,13 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re
Chunks.resize(ChunkRequests.size());
- // Unreal uses a 12 byte ID to address cache record payloads. When the uncompressed hash (ChunkId)
- // is missing, load the cache record and try to find the raw hash from the payload ID.
+ // Unreal uses a 12 byte ID to address cache record values. When the uncompressed hash (ChunkId)
+ // is missing, load the cache record and try to find the raw hash from the ValueId.
{
const auto GetChunkIdFromPayloadId = [](CbObjectView Record, const Oid& PayloadId) -> IoHash {
if (PayloadId)
{
- // A valid PayloadId indicates that the caller is searching for a Payload in a Record
+ // A valid ValueId indicates that the caller is searching for a Value in a Record
// that was Put with ICacheStore::Put
for (CbFieldView ValueView : Record["Values"sv])
{
@@ -1079,7 +1042,7 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re
}
else
{
- // An invalid PayloadId indicates that the caller is requesting a Value that
+ // An invalid ValueId indicates that the caller is requesting a Value that
// was Put with ICacheStore::PutValue
return Record["RawHash"sv].AsHash();
}
@@ -1115,8 +1078,8 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re
for (size_t RequestIndex = 0; const CacheChunkRequest& ChunkRequest : ChunkRequests)
{
- const bool QueryLocal = (ChunkRequest.Policy & CachePolicy::QueryLocal) == CachePolicy::QueryLocal;
- const bool QueryRemote = (ChunkRequest.Policy & CachePolicy::QueryRemote) == CachePolicy::QueryRemote;
+ const bool QueryLocal = EnumHasAllFlags(ChunkRequest.Policy, CachePolicy::QueryLocal);
+ const bool QueryRemote = EnumHasAllFlags(ChunkRequest.Policy, CachePolicy::QueryRemote);
if (QueryLocal)
{