From 82a032af24dfefa508c384536e6b5b7dbe65ccb8 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Fri, 1 Oct 2021 13:29:02 +0200 Subject: Improved error handling for upstream endpoints. --- zenserver/cache/structuredcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index dc96aecae..e45a26fb9 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -712,7 +712,7 @@ HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Reques if (!Payload) { - ZEN_DEBUG("MISS - '{}/{}/{}'", Ref.BucketSegment, Ref.HashKey, Ref.PayloadId); + ZEN_DEBUG("MISS - '{}/{}/{}' '{}'", Ref.BucketSegment, Ref.HashKey, Ref.PayloadId, ToString(Request.AcceptContentType())); return Request.WriteResponse(HttpResponseCode::NotFound); } -- cgit v1.2.3 From be6e8143f2ea0c4acc87608f651058627b2c229c Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Fri, 1 Oct 2021 14:45:59 +0200 Subject: Added cache HIT/MISS stat counters. --- zenserver/cache/structuredcache.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index e45a26fb9..ada19216c 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -405,6 +405,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request if (!Success) { ZEN_DEBUG("MISS - '{}/{}' '{}'", Ref.BucketSegment, Ref.HashKey, ToString(AcceptType)); + m_CacheStats.MissCount++; return Request.WriteResponse(HttpResponseCode::NotFound); } @@ -449,6 +450,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request ValidCount, AttachmentCount); + m_CacheStats.MissCount++; return Request.WriteResponse(HttpResponseCode::NotFound, HttpContentType::kText, "Missing attachments"sv); } } @@ -467,6 +469,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request IoBuffer Response(IoBuffer::Clone, MemStream.Data(), MemStream.Size()); + m_CacheStats.HitCount++; Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kCbPackage, Response); } else @@ -478,6 +481,12 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request ToString(Value.Value.GetContentType()), InUpstreamCache ? "UPSTREAM" : "LOCAL"); + m_CacheStats.HitCount++; + if (InUpstreamCache) + { + m_CacheStats.UpstreamHitCount++; + } + Request.WriteResponse(HttpResponseCode::OK, Value.Value.GetContentType(), Value.Value); } } @@ -713,6 +722,7 @@ HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Reques if (!Payload) { ZEN_DEBUG("MISS - '{}/{}/{}' '{}'", Ref.BucketSegment, Ref.HashKey, Ref.PayloadId, ToString(Request.AcceptContentType())); + m_CacheStats.MissCount++; return Request.WriteResponse(HttpResponseCode::NotFound); } @@ -724,6 +734,12 @@ HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Reques ToString(Payload.GetContentType()), InUpstreamCache ? "UPSTREAM" : "LOCAL"); + m_CacheStats.HitCount++; + if (InUpstreamCache) + { + m_CacheStats.UpstreamHitCount++; + } + Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kBinary, Payload); } @@ -845,6 +861,17 @@ HttpStructuredCacheService::HandleStatusRequest(zen::HttpServerRequest& Request) Cbo << "ok" << true; EmitSnapshot("requests", m_HttpRequests, Cbo); + + const uint64_t HitCount = m_CacheStats.HitCount; + const uint64_t UpstreamHitCount = m_CacheStats.UpstreamHitCount; + const uint64_t MissCount = m_CacheStats.MissCount; + const uint64_t TotalCount = HitCount + MissCount; + + Cbo.BeginObject("cache"); + Cbo << "hit_ratio" << (TotalCount > 0 ? (double(HitCount) / double(TotalCount) * 100.0) : 0.0); + Cbo << "upstream_ratio" << (HitCount > 0 ? (double(UpstreamHitCount) / double(HitCount)) * 100.0 : 0.0); + Cbo.EndObject(); + if (m_UpstreamCache) { Cbo.BeginObject("upstream"); -- cgit v1.2.3 From 911d3026f23a7560c3d614dffa2c6654d37b4571 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Fri, 1 Oct 2021 18:02:33 +0200 Subject: structured cache: Fixed package payload endpoint handling of HEAD --- zenserver/cache/structuredcache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index e45a26fb9..a4a19881c 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -667,11 +667,11 @@ HttpStructuredCacheService::HandleCachePayloadRequest(HttpServerRequest& Request case kHead: case kGet: { - HandleGetCachePayload(Request, Ref, Policy); if (Verb == kHead) { Request.SetSuppressResponseBody(); } + HandleGetCachePayload(Request, Ref, Policy); } break; case kPut: -- cgit v1.2.3 From b049249d3285dbe73d608431038f2502c779c2f1 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Sat, 2 Oct 2021 16:51:27 +0200 Subject: structured cache: Added some more stats (hits/misses/upstream_hits) --- zenserver/cache/structuredcache.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 8ab0276c5..dc22a15d1 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -868,7 +868,9 @@ HttpStructuredCacheService::HandleStatusRequest(zen::HttpServerRequest& Request) const uint64_t TotalCount = HitCount + MissCount; Cbo.BeginObject("cache"); + Cbo << "hits" << HitCount << "misses" << MissCount; Cbo << "hit_ratio" << (TotalCount > 0 ? (double(HitCount) / double(TotalCount) * 100.0) : 0.0); + Cbo << "upstream_hits" << m_CacheStats.UpstreamHitCount; Cbo << "upstream_ratio" << (HitCount > 0 ? (double(UpstreamHitCount) / double(HitCount)) * 100.0 : 0.0); Cbo.EndObject(); -- cgit v1.2.3 From c058fb0a11f9843d30bfdc3cd5d1d3a6bd26c3d5 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Sun, 3 Oct 2021 16:25:43 +0200 Subject: Added support for SkipData cache policy. --- zenserver/cache/structuredcache.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 8ab0276c5..fe9fdd415 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -418,10 +418,17 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request if (ValidationResult != CbValidateError::None) { ZEN_WARN("GET - '{}/{}' '{}' FAILED, invalid compact binary object", Ref.BucketSegment, Ref.HashKey, ToString(AcceptType)); + m_CacheStats.MissCount++; return Request.WriteResponse(HttpResponseCode::NotFound, HttpContentType::kText, "Invalid cache record"sv); } - const bool SkipAttachments = zen::CachePolicy::SkipAttachments == (Policy & zen::CachePolicy::SkipAttachments); + if ((Policy & CachePolicy::SkipData) == CachePolicy::SkipData) + { + m_CacheStats.HitCount++; + return Request.WriteResponse(HttpResponseCode::OK); + } + + const bool SkipAttachments = (Policy & CachePolicy::SkipAttachments) == CachePolicy::SkipAttachments; uint32_t AttachmentCount = 0; uint32_t ValidCount = 0; uint64_t AttachmentBytes = 0ull; @@ -487,7 +494,14 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request m_CacheStats.UpstreamHitCount++; } - Request.WriteResponse(HttpResponseCode::OK, Value.Value.GetContentType(), Value.Value); + if ((Policy & CachePolicy::SkipData) == CachePolicy::SkipData) + { + Request.WriteResponse(HttpResponseCode::OK); + } + else + { + Request.WriteResponse(HttpResponseCode::OK, Value.Value.GetContentType(), Value.Value); + } } } @@ -740,7 +754,14 @@ HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Reques m_CacheStats.UpstreamHitCount++; } - Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kBinary, Payload); + if ((Policy & CachePolicy::SkipData) == CachePolicy::SkipData) + { + Request.WriteResponse(HttpResponseCode::OK); + } + else + { + Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kBinary, Payload); + } } void -- cgit v1.2.3 From 5ad46537b07f1bf30af58c8cc2b85b64e45ee4c3 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Sun, 3 Oct 2021 17:00:52 +0200 Subject: structurec cache: Added ad hoc special case for /z$/stats.json request --- zenserver/cache/structuredcache.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 8ab0276c5..d7b409c6c 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -200,8 +200,10 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request) { std::string_view Key = Request.RelativeUri(); - if (Key.empty()) + if (Key.empty() || Key == "stats.json") { + $.Cancel(); + return HandleStatusRequest(Request); } -- cgit v1.2.3 From 18186784b56fe81d2ef5e7e53398491d494f7551 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Sun, 3 Oct 2021 20:11:05 +0200 Subject: http: Moved logic for body suppression to a more central location this should prevent some mistake-induced bugs hopefully --- zenserver/cache/structuredcache.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 72fc7f3af..d6174caf6 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -272,10 +272,6 @@ HttpStructuredCacheService::HandleCacheRecordRequest(HttpServerRequest& Request, case kHead: case kGet: { - if (Verb == kHead) - { - Request.SetSuppressResponseBody(); - } HandleGetCacheRecord(Request, Ref, Policy); } break; @@ -692,10 +688,6 @@ HttpStructuredCacheService::HandleCachePayloadRequest(HttpServerRequest& Request case kHead: case kGet: { - if (Verb == kHead) - { - Request.SetSuppressResponseBody(); - } HandleGetCachePayload(Request, Ref, Policy); } break; -- cgit v1.2.3 From 20ac7384f8ca558f1fb933eda846604792240ea0 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Tue, 5 Oct 2021 22:25:53 +0200 Subject: Merged from upstream --- zenserver/cache/structuredcache.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index d6174caf6..27bb1c5cd 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -12,6 +12,7 @@ #include #include +#include "monitoring/httpstats.h" #include "structuredcache.h" #include "structuredcachestore.h" #include "upstream/jupiter.h" @@ -149,13 +150,19 @@ ParseCachePolicy(const HttpServerRequest::QueryParams& QueryParams) HttpStructuredCacheService::HttpStructuredCacheService(ZenCacheStore& InCacheStore, CasStore& InStore, CidStore& InCidStore, + HttpStatsService& StatsService, + HttpStatusService& StatusService, std::unique_ptr UpstreamCache) : m_Log(logging::Get("cache")) , m_CacheStore(InCacheStore) +, m_StatsService(StatsService) +, m_StatusService(StatusService) , m_CasStore(InStore) , m_CidStore(InCidStore) , m_UpstreamCache(std::move(UpstreamCache)) { + StatsService.RegisterHandler("z$", *this); + StatusService.RegisterHandler("z$", *this); } HttpStructuredCacheService::~HttpStructuredCacheService() @@ -200,13 +207,6 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request) { std::string_view Key = Request.RelativeUri(); - if (Key.empty() || Key == "stats.json") - { - $.Cancel(); - - return HandleStatusRequest(Request); - } - if (std::all_of(begin(Key), end(Key), [](const char c) { return std::isalnum(c); })) { // Bucket reference @@ -870,10 +870,9 @@ HttpStructuredCacheService::ValidateKeyUri(HttpServerRequest& Request, CacheRef& } void -HttpStructuredCacheService::HandleStatusRequest(zen::HttpServerRequest& Request) +HttpStructuredCacheService::HandleStatsRequest(zen::HttpServerRequest& Request) { CbObjectWriter Cbo; - Cbo << "ok" << true; EmitSnapshot("requests", m_HttpRequests, Cbo); @@ -899,4 +898,12 @@ HttpStructuredCacheService::HandleStatusRequest(zen::HttpServerRequest& Request) Request.WriteResponse(HttpResponseCode::OK, Cbo.Save()); } +void +HttpStructuredCacheService::HandleStatusRequest(zen::HttpServerRequest& Request) +{ + CbObjectWriter Cbo; + Cbo << "ok" << true; + Request.WriteResponse(HttpResponseCode::OK, Cbo.Save()); +} + } // namespace zen -- cgit v1.2.3 From fa48ebf89e06edc9d3bdd26b119417df20902bdd Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Wed, 6 Oct 2021 13:59:18 +0200 Subject: Support for asynchronous HTTP response processing (#19) This change introduces WriteResponseAsync which can be used to move potentially slow request handler code (like upstream lookups) off the I/O service thread to ensure we are always able to serve as many HTTP requests as possible. The current implementation defaults to 16 async worker threads and there is currently no back-pressure. - Added RequestStats - Metrics for network requests. Aggregates tracking of duration, payload sizes into a single class for ease of use - Added some metrics on upstream communication Co-authored-by: Per Larsson --- zenserver/cache/structuredcache.cpp | 228 ++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 114 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 27bb1c5cd..4a2a3748a 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -286,28 +286,104 @@ HttpStructuredCacheService::HandleCacheRecordRequest(HttpServerRequest& Request, void HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request, const CacheRef& Ref, CachePolicy Policy) { - const ZenContentType AcceptType = Request.AcceptContentType(); + const ZenContentType AcceptType = Request.AcceptContentType(); + const bool SkipData = (Policy & CachePolicy::SkipData) == CachePolicy::SkipData; + const bool SkipAttachments = (Policy & CachePolicy::SkipAttachments) == CachePolicy::SkipAttachments; + const bool QueryUpstream = m_UpstreamCache && ((Policy & CachePolicy::QueryRemote) == CachePolicy::QueryRemote); - ZenCacheValue Value; - bool Success = m_CacheStore.Get(Ref.BucketSegment, Ref.HashKey, /* out */ Value); - bool InUpstreamCache = false; + bool Success = false; + ZenCacheValue LocalCacheValue; - const bool QueryUpstream = !Success && m_UpstreamCache && (CachePolicy::QueryRemote == (Policy & CachePolicy::QueryRemote)); + if (m_CacheStore.Get(Ref.BucketSegment, Ref.HashKey, LocalCacheValue)) + { + Success = true; - if (QueryUpstream) + if (!SkipData && AcceptType == ZenContentType::kCbPackage) + { + CbPackage Package; + CbObjectView CacheRecord(LocalCacheValue.Value.Data()); + uint32_t AttachmentCount = 0; + uint32_t ValidCount = 0; + + if (!SkipAttachments) + { + CacheRecord.IterateAttachments([this, &Ref, &Package, &AttachmentCount, &ValidCount](CbFieldView AttachmentHash) { + if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash())) + { + Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk)))); + ValidCount++; + } + AttachmentCount++; + }); + + if (ValidCount != AttachmentCount) + { + Success = false; + ZEN_WARN("GET - '{}/{}' '{}' FAILED, found '{}' of '{}' attachments", + Ref.BucketSegment, + Ref.HashKey, + ToString(AcceptType), + ValidCount, + AttachmentCount); + } + } + + Package.SetObject(LoadCompactBinaryObject(LocalCacheValue.Value)); + + BinaryWriter MemStream; + Package.Save(MemStream); + + LocalCacheValue.Value = IoBuffer(IoBuffer::Clone, MemStream.Data(), MemStream.Size()); + LocalCacheValue.Value.SetContentType(HttpContentType::kCbPackage); + } + } + + if (Success) { - const ZenContentType CacheRecordType = AcceptType; + ZEN_DEBUG("HIT - '{}/{}' {} '{}' (LOCAL)", + Ref.BucketSegment, + Ref.HashKey, + NiceBytes(LocalCacheValue.Value.Size()), + ToString(LocalCacheValue.Value.GetContentType())); - if (auto UpstreamResult = m_UpstreamCache->GetCacheRecord({Ref.BucketSegment, Ref.HashKey}, CacheRecordType); + m_CacheStats.HitCount++; + + if (SkipData) + { + return Request.WriteResponse(HttpResponseCode::OK); + } + else + { + return Request.WriteResponse(HttpResponseCode::OK, LocalCacheValue.Value.GetContentType(), LocalCacheValue.Value); + } + } + else if (!QueryUpstream) + { + ZEN_DEBUG("MISS - '{}/{}' '{}'", Ref.BucketSegment, Ref.HashKey, ToString(AcceptType)); + m_CacheStats.MissCount++; + return Request.WriteResponse(HttpResponseCode::NotFound); + } + + // 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, Ref](HttpServerRequest& AsyncRequest) { + bool Success = false; + ZenCacheValue UpstreamCacheValue; + + metrics::OperationTiming::Scope $(m_UpstreamGetRequestTiming); + + if (GetUpstreamCacheResult UpstreamResult = m_UpstreamCache->GetCacheRecord({Ref.BucketSegment, Ref.HashKey}, AcceptType); UpstreamResult.Success) { - Value.Value = UpstreamResult.Value; - Success = true; - InUpstreamCache = true; + Success = true; + UpstreamCacheValue.Value = UpstreamResult.Value; + + UpstreamCacheValue.Value.SetContentType(AcceptType); - if (CacheRecordType == ZenContentType::kBinary || CacheRecordType == ZenContentType::kCbObject) + if (AcceptType == ZenContentType::kBinary || AcceptType == ZenContentType::kCbObject) { - if (CacheRecordType == ZenContentType::kCbObject) + if (AcceptType == ZenContentType::kCbObject) { const CbValidateError ValidationResult = ValidateCompactBinary(UpstreamResult.Value, CbValidateMode::All); @@ -320,7 +396,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request CacheRecord.IterateAttachments([&](CbFieldView Attachment) { IndexData.AddHash(Attachment.AsHash()); }); IndexData.EndArray(); - Value.IndexData = IndexData.Save(); + UpstreamCacheValue.IndexData = IndexData.Save(); } else { @@ -334,19 +410,17 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request if (Success) { - m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, Value); + m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, UpstreamCacheValue); } } - else + else if (AcceptType == ZenContentType::kCbPackage) { - ZEN_ASSERT(CacheRecordType == ZenContentType::kCbPackage); - CbPackage Package; - if (Package.TryLoad(UpstreamResult.Value)) + if (Package.TryLoad(UpstreamCacheValue.Value)) { + CbObject CacheRecord = Package.GetObject(); uint32_t AttachmentCount = 0; uint32_t ValidCount = 0; - CbObject CacheRecord = Package.GetObject(); CacheRecord.IterateAttachments([this, &Package, &Ref, &AttachmentCount, &ValidCount](CbFieldView AttachmentHash) { if (const CbAttachment* Attachment = Package.FindAttachment(AttachmentHash.AsHash())) @@ -371,7 +445,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request { m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, {.Value = CacheRecord.GetBuffer().AsIoBuffer()}); - if (zen::CachePolicy::SkipAttachments == (Policy & zen::CachePolicy::SkipAttachments)) + if (SkipAttachments) { CbPackage PackageWithoutAttachments; PackageWithoutAttachments.SetObject(CacheRecord); @@ -379,7 +453,7 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request BinaryWriter MemStream; PackageWithoutAttachments.Save(MemStream); - Value.Value = IoBuffer(IoBuffer::Clone, MemStream.Data(), MemStream.Size()); + UpstreamCacheValue.Value = IoBuffer(IoBuffer::Clone, MemStream.Data(), MemStream.Size()); } } else @@ -398,109 +472,34 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request } } } - } - - if (!Success) - { - ZEN_DEBUG("MISS - '{}/{}' '{}'", Ref.BucketSegment, Ref.HashKey, ToString(AcceptType)); - m_CacheStats.MissCount++; - return Request.WriteResponse(HttpResponseCode::NotFound); - } - - if (AcceptType == ZenContentType::kCbPackage && !InUpstreamCache) - { - CbObjectView CacheRecord(Value.Value.Data()); - const CbValidateError ValidationResult = ValidateCompactBinary(Value.Value, CbValidateMode::All); - - if (ValidationResult != CbValidateError::None) + if (Success) { - ZEN_WARN("GET - '{}/{}' '{}' FAILED, invalid compact binary object", Ref.BucketSegment, Ref.HashKey, ToString(AcceptType)); - m_CacheStats.MissCount++; - return Request.WriteResponse(HttpResponseCode::NotFound, HttpContentType::kText, "Invalid cache record"sv); - } + ZEN_DEBUG("HIT - '{}/{}' {} '{}' (UPSTREAM)", + Ref.BucketSegment, + Ref.HashKey, + NiceBytes(UpstreamCacheValue.Value.Size()), + ToString(UpstreamCacheValue.Value.GetContentType())); - if ((Policy & CachePolicy::SkipData) == CachePolicy::SkipData) - { m_CacheStats.HitCount++; - return Request.WriteResponse(HttpResponseCode::OK); - } - - const bool SkipAttachments = (Policy & CachePolicy::SkipAttachments) == CachePolicy::SkipAttachments; - uint32_t AttachmentCount = 0; - uint32_t ValidCount = 0; - uint64_t AttachmentBytes = 0ull; - - CbPackage Package; - - if (!SkipAttachments) - { - CacheRecord.IterateAttachments( - [this, &Ref, &Package, &AttachmentCount, &ValidCount, &AttachmentBytes](CbFieldView AttachmentHash) { - if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash())) - { - Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk)))); - AttachmentBytes += Chunk.Size(); - ValidCount++; - } - AttachmentCount++; - }); + m_CacheStats.UpstreamHitCount++; - if (ValidCount != AttachmentCount) + if (SkipData) { - ZEN_WARN("GET - '{}/{}' '{}' FAILED, found '{}' of '{}' attachments", - Ref.BucketSegment, - Ref.HashKey, - ToString(AcceptType), - ValidCount, - AttachmentCount); - - m_CacheStats.MissCount++; - return Request.WriteResponse(HttpResponseCode::NotFound, HttpContentType::kText, "Missing attachments"sv); + AsyncRequest.WriteResponse(HttpResponseCode::OK); + } + else + { + AsyncRequest.WriteResponse(HttpResponseCode::OK, UpstreamCacheValue.Value.GetContentType(), UpstreamCacheValue.Value); } - } - - Package.SetObject(LoadCompactBinaryObject(Value.Value)); - - ZEN_DEBUG("HIT - '{}/{}' {} '{}', {} attachments (LOCAL)", - Ref.BucketSegment, - Ref.HashKey, - NiceBytes(AttachmentBytes + Value.Value.Size()), - ToString(HttpContentType::kCbPackage), - AttachmentCount); - - BinaryWriter MemStream; - Package.Save(MemStream); - - IoBuffer Response(IoBuffer::Clone, MemStream.Data(), MemStream.Size()); - - m_CacheStats.HitCount++; - Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kCbPackage, Response); - } - else - { - ZEN_DEBUG("HIT - '{}/{}' {} '{}' ({})", - Ref.BucketSegment, - Ref.HashKey, - NiceBytes(Value.Value.Size()), - ToString(Value.Value.GetContentType()), - InUpstreamCache ? "UPSTREAM" : "LOCAL"); - - m_CacheStats.HitCount++; - if (InUpstreamCache) - { - m_CacheStats.UpstreamHitCount++; - } - - if ((Policy & CachePolicy::SkipData) == CachePolicy::SkipData) - { - Request.WriteResponse(HttpResponseCode::OK); } else { - Request.WriteResponse(HttpResponseCode::OK, Value.Value.GetContentType(), Value.Value); + ZEN_DEBUG("MISS - '{}/{}' '{}'", Ref.BucketSegment, Ref.HashKey, ToString(AcceptType)); + m_CacheStats.MissCount++; + AsyncRequest.WriteResponse(HttpResponseCode::NotFound); } - } + }); } void @@ -875,6 +874,7 @@ HttpStructuredCacheService::HandleStatsRequest(zen::HttpServerRequest& Request) CbObjectWriter Cbo; EmitSnapshot("requests", m_HttpRequests, Cbo); + EmitSnapshot("upstream_gets", m_UpstreamGetRequestTiming, Cbo); const uint64_t HitCount = m_CacheStats.HitCount; const uint64_t UpstreamHitCount = m_CacheStats.UpstreamHitCount; -- cgit v1.2.3