From a9298af536e76ce922411f94a6cb4683e5da09ad Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Mon, 15 Nov 2021 09:47:03 +0100 Subject: Handle 'partial on error' cache policy. --- zenserver/cache/structuredcache.cpp | 50 ++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 15 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index eb31ce5e6..726bd7cdb 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -473,7 +473,7 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request TotalCount++; }); - ZEN_DEBUG("PUT - '{}/{}' {} '{}' attachments '{}/{}' (Valid/Total)", + ZEN_DEBUG("PUT - '{}/{}' {} '{}' attachments '{}/{}' (valid/total)", Ref.BucketSegment, Ref.HashKey, NiceBytes(Body.Size()), @@ -552,7 +552,7 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid attachment(s)"sv); } - ZEN_DEBUG("PUT - '{}/{}' {} '{}', attachments '{}/{}/{}' (New/Valid/Total)", + ZEN_DEBUG("PUT - '{}/{}' {} '{}', attachments '{}/{}/{}' (new/valid/total)", Ref.BucketSegment, Ref.HashKey, NiceBytes(Body.GetSize()), @@ -831,8 +831,9 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req CacheRecordPolicy::Load(Params["Policy"sv].AsObjectView(), Policy); - const bool SkipAttachments = (Policy.GetRecordPolicy() & CachePolicy::SkipAttachments) == CachePolicy::SkipAttachments; - const bool QueryRemote = m_UpstreamCache && ((Policy.GetRecordPolicy() & CachePolicy::QueryRemote) == CachePolicy::QueryRemote); + const bool PartialOnError = Policy.HasRecordPolicy(CachePolicy::PartialOnError); + const bool SkipAttachments = Policy.HasRecordPolicy(CachePolicy::SkipAttachments); + const bool QueryRemote = Policy.HasRecordPolicy(CachePolicy::QueryRemote) && m_UpstreamCache; for (CbFieldView KeyView : Params["CacheKeys"sv]) { @@ -850,27 +851,36 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req for (size_t KeyIndex = 0; const CacheKey& Key : CacheKeys) { ZenCacheValue CacheValue; + uint32_t MissingCount = 0; + if (m_CacheStore.Get(Key.Bucket, Key.Hash, CacheValue)) { CbObjectView CacheRecord(CacheValue.Value.Data()); if (!SkipAttachments) { - CacheRecord.IterateAttachments([this, &RpcResponse](CbFieldView AttachmentHash) { + CacheRecord.IterateAttachments([this, &MissingCount, &RpcResponse](CbFieldView AttachmentHash) { if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash())) { RpcResponse.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk)))); } + else + { + MissingCount++; + } }); } + } + if (CacheValue.Value && (MissingCount == 0 || PartialOnError)) + { ZEN_DEBUG("HIT - '{}/{}' {} '{}' (LOCAL)", Key.Bucket, Key.Hash, NiceBytes(CacheValue.Value.Size()), ToString(CacheValue.Value.GetContentType())); - CacheValues[KeyIndex] = CacheValue.Value; + CacheValues[KeyIndex] = std::move(CacheValue.Value); m_CacheStats.HitCount++; } else if (QueryRemote) @@ -879,7 +889,7 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req } else { - ZEN_DEBUG("MISS - '{}/{}'", Key.Bucket, Key.Hash); + ZEN_DEBUG("MISS - '{}/{}' {}", Key.Bucket, Key.Hash, MissingCount ? "(partial)"sv : ""sv); m_CacheStats.MissCount++; } @@ -889,10 +899,14 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req if (!UpstreamRequests.empty() && m_UpstreamCache) { const auto OnCacheRecordGetComplete = - [this, &CacheKeys, &CacheValues, &RpcResponse, SkipAttachments](CacheRecordGetCompleteParams&& Params) { + [this, &CacheKeys, &CacheValues, &RpcResponse, PartialOnError, SkipAttachments](CacheRecordGetCompleteParams&& Params) { + ZEN_ASSERT(Params.KeyIndex < CacheValues.size()); + + IoBuffer CacheValue; + AttachmentCount Count; + if (Params.Record) { - AttachmentCount Count; Params.Record.IterateAttachments([this, &RpcResponse, SkipAttachments, &Params, &Count](CbFieldView HashView) { if (const CbAttachment* Attachment = Params.Package.FindAttachment(HashView.AsHash())) { @@ -926,18 +940,23 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req Count.Total++; }); - ZEN_DEBUG("HIT - '{}/{}' {} '{}' attachments '{}/{}/{}' (New/Valid/Total) (UPSTREAM)", + if ((Count.Valid == Count.Total) || PartialOnError) + { + CacheValue = CbObject::Clone(Params.Record).GetBuffer().AsIoBuffer(); + } + } + + if (CacheValue) + { + ZEN_DEBUG("HIT - '{}/{}' {} '{}' attachments '{}/{}/{}' (new/valid/total) (UPSTREAM)", Params.CacheKey.Bucket, Params.CacheKey.Hash, - NiceBytes(Params.Record.GetView().GetSize()), + NiceBytes(CacheValue.GetSize()), ToString(HttpContentType::kCbPackage), Count.New, Count.Valid, Count.Total); - ZEN_ASSERT(Params.KeyIndex < CacheValues.size()); - - IoBuffer CacheValue = CbObject::Clone(Params.Record).GetBuffer().AsIoBuffer(); CacheValue.SetContentType(ZenContentType::kCbObject); CacheValues[Params.KeyIndex] = CacheValue; @@ -948,7 +967,8 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req } else { - ZEN_DEBUG("MISS - '{}/{}'", Params.CacheKey.Bucket, Params.CacheKey.Hash); + const bool IsPartial = Count.Valid != Count.Total; + ZEN_DEBUG("MISS - '{}/{}' {}", Params.CacheKey.Bucket, Params.CacheKey.Hash, IsPartial ? "(partial)"sv : ""sv); m_CacheStats.MissCount++; } }; -- cgit v1.2.3