diff options
Diffstat (limited to 'zenserver/cache/structuredcache.cpp')
| -rw-r--r-- | zenserver/cache/structuredcache.cpp | 115 |
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 |