aboutsummaryrefslogtreecommitdiff
path: root/zenserver/cache/structuredcache.cpp
diff options
context:
space:
mode:
authormattpetersepic <[email protected]>2022-01-26 13:54:39 -0700
committerGitHub <[email protected]>2022-01-26 13:54:39 -0700
commit88ed064ce4e4e5e3fe5d3856b3c4eac9550e69d7 (patch)
tree5aa00cc38dbf949456a88d2d9349fe46ad279583 /zenserver/cache/structuredcache.cpp
parentMerge branch 'main' of https://github.com/EpicGames/zen (diff)
downloadzen-88ed064ce4e4e5e3fe5d3856b3c4eac9550e69d7.tar.xz
zen-88ed064ce4e4e5e3fe5d3856b3c4eac9550e69d7.zip
Implement SkipData,QueryLocal,StoreLocal for GET-verb CacheGet requests (#39)
* Implement SkipData,QueryLocal,StoreLocal for GET-verb CacheGet requests
Diffstat (limited to 'zenserver/cache/structuredcache.cpp')
-rw-r--r--zenserver/cache/structuredcache.cpp115
1 files changed, 75 insertions, 40 deletions
diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp
index 8854ff3d1..228d33202 100644
--- a/zenserver/cache/structuredcache.cpp
+++ b/zenserver/cache/structuredcache.cpp
@@ -202,12 +202,15 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
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;
+ ZenCacheValue ClientResultValue;
+ if (!EnumHasAnyFlags(PolicyFromURL, CachePolicy::Query))
+ {
+ return Request.WriteResponse(HttpResponseCode::OK);
+ }
- if (m_CacheStore.Get(Ref.BucketSegment, Ref.HashKey, LocalCacheValue))
+ if (EnumHasAllFlags(PolicyFromURL, CachePolicy::QueryLocal) && m_CacheStore.Get(Ref.BucketSegment, Ref.HashKey, ClientResultValue))
{
Success = true;
@@ -216,15 +219,22 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
CbPackage Package;
uint32_t MissingCount = 0;
- CbObjectView CacheRecord(LocalCacheValue.Value.Data());
- CacheRecord.IterateAttachments([this, &MissingCount, &Package](CbFieldView AttachmentHash) {
- if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash()))
+ CbObjectView CacheRecord(ClientResultValue.Value.Data());
+ CacheRecord.IterateAttachments([this, &MissingCount, &Package, SkipData](CbFieldView AttachmentHash) {
+ if (SkipData)
{
- Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk))));
+ MissingCount += m_CidStore.ContainsChunk(AttachmentHash.AsHash()) ? 0 : 1;
}
else
{
- MissingCount++;
+ if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash()))
+ {
+ Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk))));
+ }
+ else
+ {
+ MissingCount++;
+ }
}
});
@@ -232,13 +242,13 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
if (Success)
{
- Package.SetObject(LoadCompactBinaryObject(LocalCacheValue.Value));
+ Package.SetObject(LoadCompactBinaryObject(ClientResultValue.Value));
BinaryWriter MemStream;
Package.Save(MemStream);
- LocalCacheValue.Value = IoBuffer(IoBuffer::Clone, MemStream.Data(), MemStream.Size());
- LocalCacheValue.Value.SetContentType(HttpContentType::kCbPackage);
+ ClientResultValue.Value = IoBuffer(IoBuffer::Clone, MemStream.Data(), MemStream.Size());
+ ClientResultValue.Value.SetContentType(HttpContentType::kCbPackage);
}
}
}
@@ -248,21 +258,21 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
ZEN_DEBUG("HIT - '{}/{}' {} '{}' (LOCAL)",
Ref.BucketSegment,
Ref.HashKey,
- NiceBytes(LocalCacheValue.Value.Size()),
- ToString(LocalCacheValue.Value.GetContentType()));
+ NiceBytes(ClientResultValue.Value.Size()),
+ ToString(ClientResultValue.Value.GetContentType()));
m_CacheStats.HitCount++;
-
- if (SkipData)
+ if (SkipData && AcceptType == ZenContentType::kBinary)
{
return Request.WriteResponse(HttpResponseCode::OK);
}
else
{
- return Request.WriteResponse(HttpResponseCode::OK, LocalCacheValue.Value.GetContentType(), LocalCacheValue.Value);
+ // Other types handled SkipData when constructing the ClientResultValue
+ return Request.WriteResponse(HttpResponseCode::OK, ClientResultValue.Value.GetContentType(), ClientResultValue.Value);
}
}
- else if (!QueryUpstream)
+ else if (!EnumHasAllFlags(PolicyFromURL, CachePolicy::QueryRemote))
{
ZEN_DEBUG("MISS - '{}/{}' '{}'", Ref.BucketSegment, Ref.HashKey, ToString(AcceptType));
m_CacheStats.MissCount++;
@@ -272,9 +282,13 @@ 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, PartialRecord, Ref](HttpServerRequest& AsyncRequest) {
- bool Success = false;
- ZenCacheValue UpstreamCacheValue;
+ Request.WriteResponseAsync([this, AcceptType, PolicyFromURL, Ref](HttpServerRequest& AsyncRequest) {
+ bool Success = false;
+ const bool PartialRecord = EnumHasAllFlags(PolicyFromURL, CachePolicy::PartialRecord);
+ const bool QueryLocal = EnumHasAllFlags(PolicyFromURL, CachePolicy::QueryLocal);
+ const bool StoreLocal = EnumHasAllFlags(PolicyFromURL, CachePolicy::StoreLocal);
+ const bool SkipData = EnumHasAllFlags(PolicyFromURL, CachePolicy::SkipData);
+ ZenCacheValue ClientResultValue;
metrics::OperationTiming::Scope $(m_UpstreamGetRequestTiming);
@@ -283,8 +297,8 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
{
Success = true;
- UpstreamCacheValue.Value = UpstreamResult.Value;
- UpstreamCacheValue.Value.SetContentType(AcceptType);
+ ClientResultValue.Value = UpstreamResult.Value;
+ ClientResultValue.Value.SetContentType(AcceptType);
if (AcceptType == ZenContentType::kBinary || AcceptType == ZenContentType::kCbObject)
{
@@ -299,30 +313,35 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
Ref.HashKey,
ToString(AcceptType));
}
+
+ // We do not do anything to the returned object for SkipData, only package attachments are cut when skipping data
}
- if (Success)
+ if (Success && StoreLocal)
{
- m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, UpstreamCacheValue);
+ m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, ClientResultValue);
}
}
else if (AcceptType == ZenContentType::kCbPackage)
{
CbPackage Package;
- if (Package.TryLoad(UpstreamCacheValue.Value))
+ if (Package.TryLoad(ClientResultValue.Value))
{
CbObject CacheRecord = Package.GetObject();
AttachmentCount Count;
- CacheRecord.IterateAttachments([this, &Package, &Ref, &Count](CbFieldView HashView) {
+ CacheRecord.IterateAttachments([this, &Package, &Ref, &Count, QueryLocal, StoreLocal](CbFieldView HashView) {
if (const CbAttachment* Attachment = Package.FindAttachment(HashView.AsHash()))
{
if (CompressedBuffer Compressed = Attachment->AsCompressedBinary())
{
- auto InsertResult = m_CidStore.AddChunk(Compressed);
- if (InsertResult.New)
+ if (StoreLocal)
{
- Count.New++;
+ auto InsertResult = m_CidStore.AddChunk(Compressed);
+ if (InsertResult.New)
+ {
+ Count.New++;
+ }
}
Count.Valid++;
}
@@ -335,10 +354,13 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
Count.Invalid++;
}
}
- else if (IoBuffer Chunk = m_CidStore.FindChunkByCid(HashView.AsHash()))
+ else if (QueryLocal)
{
- Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk))));
- Count.Valid++;
+ if (IoBuffer Chunk = m_CidStore.FindChunkByCid(HashView.AsHash()))
+ {
+ Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk))));
+ Count.Valid++;
+ }
}
Count.Total++;
});
@@ -349,13 +371,24 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
CacheValue.Value = CacheRecord.GetBuffer().AsIoBuffer();
CacheValue.Value.SetContentType(ZenContentType::kCbObject);
- m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, CacheValue);
+ if (StoreLocal)
+ {
+ m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, CacheValue);
+ }
BinaryWriter MemStream;
- Package.Save(MemStream);
+ if (SkipData)
+ {
+ // Save a package containing only the object.
+ CbPackage(Package.GetObject()).Save(MemStream);
+ }
+ else
+ {
+ Package.Save(MemStream);
+ }
- UpstreamCacheValue.Value = IoBuffer(IoBuffer::Clone, MemStream.Data(), MemStream.Size());
- UpstreamCacheValue.Value.SetContentType(ZenContentType::kCbPackage);
+ ClientResultValue.Value = IoBuffer(IoBuffer::Clone, MemStream.Data(), MemStream.Size());
+ ClientResultValue.Value.SetContentType(ZenContentType::kCbPackage);
}
else
{
@@ -379,19 +412,21 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request
ZEN_DEBUG("HIT - '{}/{}' {} '{}' (UPSTREAM)",
Ref.BucketSegment,
Ref.HashKey,
- NiceBytes(UpstreamCacheValue.Value.Size()),
- ToString(UpstreamCacheValue.Value.GetContentType()));
+ NiceBytes(ClientResultValue.Value.Size()),
+ ToString(ClientResultValue.Value.GetContentType()));
m_CacheStats.HitCount++;
m_CacheStats.UpstreamHitCount++;
- if (SkipData)
+ if (SkipData && AcceptType == ZenContentType::kBinary)
{
AsyncRequest.WriteResponse(HttpResponseCode::OK);
}
else
{
- AsyncRequest.WriteResponse(HttpResponseCode::OK, UpstreamCacheValue.Value.GetContentType(), UpstreamCacheValue.Value);
+ // Other methods modify ClientResultValue to a version that has skipped the data but keeps the Object and optionally
+ // metadata.
+ AsyncRequest.WriteResponse(HttpResponseCode::OK, ClientResultValue.Value.GetContentType(), ClientResultValue.Value);
}
}
else