From eadca136e5db2895379dda0f1a66f019d3914a82 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Fri, 29 Oct 2021 11:14:12 +0200 Subject: First pass batch request. --- zenserver/cache/structuredcache.cpp | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 35cb02cbb..172e122e4 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -210,6 +210,13 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request) { std::string_view Key = Request.RelativeUri(); + if (Key == "$batch") + { + const auto QueryParams = Request.GetQueryParams(); + CachePolicy Policy = ParseCachePolicy(QueryParams); + return HandleBatchRequest(Request, Policy); + } + if (std::all_of(begin(Key), end(Key), [](const char c) { return std::isalnum(c); })) { // Bucket reference @@ -872,6 +879,71 @@ HttpStructuredCacheService::ValidateKeyUri(HttpServerRequest& Request, CacheRef& return true; } +void +HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request, CachePolicy Policy) +{ + ZEN_UNUSED(Policy); + + switch (auto Verb = Request.RequestVerb()) + { + using enum HttpVerb; + + case kGet: + { + const HttpContentType ContentType = Request.RequestContentType(); + const HttpContentType AcceptType = Request.AcceptContentType(); + + if (ContentType != HttpContentType::kCbObject || AcceptType != HttpContentType::kCbPackage) + { + return Request.WriteResponse(HttpResponseCode::BadRequest); + } + + CbObject BatchRequest = zen::LoadCompactBinaryObject(Request.ReadPayload()); + + CbPackage Package; + CbObjectWriter BatchResponse; + + BatchResponse.BeginArray("records"sv); + + for (CbFieldView QueryView : BatchRequest["records"sv]) + { + CbObjectView Query = QueryView.AsObjectView(); + const std::string_view Bucket = Query["bucket"sv].AsString(); + const IoHash CacheKey = Query["key"sv].AsHash(); + + ZenCacheValue CacheValue; + const bool Hit = m_CacheStore.Get(Bucket, CacheKey, CacheValue); + + if (Hit) + { + CbObjectView CacheRecord(CacheValue.Value.Data()); + + CacheRecord.IterateAttachments([this, &Package](CbFieldView AttachmentHash) { + if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash())) + { + Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk)))); + } + }); + + BatchResponse << CacheRecord; + } + } + + BatchResponse.EndArray(); + Package.SetObject(BatchResponse.Save()); + + BinaryWriter MemStream; + Package.Save(MemStream); + + Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kCbPackage, IoBuffer(IoBuffer::Wrap, MemStream.GetData(), MemStream.GetSize())); + } + break; + default: + Request.WriteResponse(HttpResponseCode::BadRequest); + break; + } +} + void HttpStructuredCacheService::HandleStatsRequest(zen::HttpServerRequest& Request) { -- cgit v1.2.3 From 4b8d4c0e375c729e38bdaadfebf0eaf14f08f5f9 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Tue, 2 Nov 2021 10:50:18 +0100 Subject: Added upstream batch API. --- zenserver/cache/structuredcache.cpp | 225 +++++++++++++++++------------------- 1 file changed, 103 insertions(+), 122 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 172e122e4..59cc74d53 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -12,6 +12,7 @@ #include #include +#include "cachekey.h" #include "monitoring/httpstats.h" #include "structuredcache.h" #include "structuredcachestore.h" @@ -36,111 +37,12 @@ using namespace std::literals; ////////////////////////////////////////////////////////////////////////// -namespace detail { namespace cacheopt { - constexpr std::string_view Local = "local"sv; - constexpr std::string_view Remote = "remote"sv; - constexpr std::string_view Data = "data"sv; - constexpr std::string_view Meta = "meta"sv; - constexpr std::string_view Value = "value"sv; - constexpr std::string_view Attachments = "attachments"sv; -}} // namespace detail::cacheopt - -////////////////////////////////////////////////////////////////////////// - -enum class CachePolicy : uint8_t -{ - None = 0, - QueryLocal = 1 << 0, - QueryRemote = 1 << 1, - Query = QueryLocal | QueryRemote, - StoreLocal = 1 << 2, - StoreRemote = 1 << 3, - Store = StoreLocal | StoreRemote, - SkipMeta = 1 << 4, - SkipValue = 1 << 5, - SkipAttachments = 1 << 6, - SkipData = SkipMeta | SkipValue | SkipAttachments, - SkipLocalCopy = 1 << 7, - Local = QueryLocal | StoreLocal, - Remote = QueryRemote | StoreRemote, - Default = Query | Store, - Disable = None, -}; - -gsl_DEFINE_ENUM_BITMASK_OPERATORS(CachePolicy); - CachePolicy ParseCachePolicy(const HttpServerRequest::QueryParams& QueryParams) { - CachePolicy QueryPolicy = CachePolicy::Query; - - { - std::string_view Opts = QueryParams.GetValue("query"sv); - if (!Opts.empty()) - { - QueryPolicy = CachePolicy::None; - ForEachStrTok(Opts, ',', [&QueryPolicy](const std::string_view& Opt) { - if (Opt == detail::cacheopt::Local) - { - QueryPolicy |= CachePolicy::QueryLocal; - } - if (Opt == detail::cacheopt::Remote) - { - QueryPolicy |= CachePolicy::QueryRemote; - } - return true; - }); - } - } - - CachePolicy StorePolicy = CachePolicy::Store; - - { - std::string_view Opts = QueryParams.GetValue("store"sv); - if (!Opts.empty()) - { - StorePolicy = CachePolicy::None; - ForEachStrTok(Opts, ',', [&StorePolicy](const std::string_view& Opt) { - if (Opt == detail::cacheopt::Local) - { - StorePolicy |= CachePolicy::StoreLocal; - } - if (Opt == detail::cacheopt::Remote) - { - StorePolicy |= CachePolicy::StoreRemote; - } - return true; - }); - } - } - - CachePolicy SkipPolicy = CachePolicy::None; - - { - std::string_view Opts = QueryParams.GetValue("skip"sv); - if (!Opts.empty()) - { - ForEachStrTok(Opts, ',', [&SkipPolicy](const std::string_view& Opt) { - if (Opt == detail::cacheopt::Meta) - { - SkipPolicy |= CachePolicy::SkipMeta; - } - if (Opt == detail::cacheopt::Value) - { - SkipPolicy |= CachePolicy::SkipValue; - } - if (Opt == detail::cacheopt::Attachments) - { - SkipPolicy |= CachePolicy::SkipAttachments; - } - if (Opt == detail::cacheopt::Data) - { - SkipPolicy |= CachePolicy::SkipData; - } - return true; - }); - } - } + 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; } @@ -882,7 +784,11 @@ HttpStructuredCacheService::ValidateKeyUri(HttpServerRequest& Request, CacheRef& void HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request, CachePolicy Policy) { - ZEN_UNUSED(Policy); + using namespace fmt::literals; + + 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); switch (auto Verb = Request.RequestVerb()) { @@ -898,44 +804,119 @@ HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request, return Request.WriteResponse(HttpResponseCode::BadRequest); } - CbObject BatchRequest = zen::LoadCompactBinaryObject(Request.ReadPayload()); + CbObject BatchRequest = zen::LoadCompactBinaryObject(Request.ReadPayload()); + const std::string_view Method = BatchRequest["method"sv].AsString(); - CbPackage Package; - CbObjectWriter BatchResponse; + if (Method != "getcacherecords"sv) + { + return Request.WriteResponse(HttpResponseCode::BadRequest, + HttpContentType::kText, + "Invalid method '{}'"_format(Method)); + } - BatchResponse.BeginArray("records"sv); + CbObjectView Params = BatchRequest["params"sv].AsObjectView(); - for (CbFieldView QueryView : BatchRequest["records"sv]) + std::vector CacheKeys; + std::vector CacheValues; + std::vector Payloads; + std::vector Missing; + + for (CbFieldView QueryView : Params["cachekeys"sv]) { - CbObjectView Query = QueryView.AsObjectView(); - const std::string_view Bucket = Query["bucket"sv].AsString(); - const IoHash CacheKey = Query["key"sv].AsHash(); + CbObjectView Query = QueryView.AsObjectView(); + CacheKeys.push_back(CacheKey::Create(Query["bucket"sv].AsString(), Query["key"sv].AsHash())); + } - ZenCacheValue CacheValue; - const bool Hit = m_CacheStore.Get(Bucket, CacheKey, CacheValue); + CacheValues.resize(CacheKeys.size()); - if (Hit) + for (size_t Idx = 0; const CacheKey& Key : CacheKeys) + { + ZenCacheValue CacheValue; + if (m_CacheStore.Get(Key.Bucket, Key.Hash, CacheValue)) { CbObjectView CacheRecord(CacheValue.Value.Data()); - CacheRecord.IterateAttachments([this, &Package](CbFieldView AttachmentHash) { - if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash())) + if (!SkipAttachments) + { + CacheRecord.IterateAttachments([this, &Payloads](CbFieldView AttachmentHash) { + if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash())) + { + Payloads.push_back(Chunk); + } + }); + } + + CacheValues[Idx] = CacheValue.Value; + } + else + { + Missing.push_back(Idx); + } + + ++Idx; + } + + if (QueryUpstream) + { + auto UpstreamResult = m_UpstreamCache->GetCacheRecords( + CacheKeys, + Missing, + [this, &CacheValues, &Payloads, SkipAttachments](size_t KeyIndex, IoBuffer UpstreamValue) { + CbPackage UpstreamPackage; + if (UpstreamValue && UpstreamPackage.TryLoad(UpstreamValue)) { - Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk)))); + CbObjectView CacheRecord = UpstreamPackage.GetObject(); + + CacheRecord.IterateAttachments([&](CbFieldView AttachmentHash) { + if (const CbAttachment* Attachment = UpstreamPackage.FindAttachment(AttachmentHash.AsHash())) + { + if (CompressedBuffer Chunk = Attachment->AsCompressedBinary()) + { + m_CidStore.AddChunk(Chunk); + + if (!SkipAttachments) + { + Payloads.push_back(Chunk.GetCompressed().Flatten().AsIoBuffer()); + } + } + } + }); + + CacheValues[KeyIndex] = IoBufferBuilder::MakeCloneFromMemory(CacheRecord.GetView()); } }); + } + + CbObjectWriter BatchResponse; - BatchResponse << CacheRecord; + BatchResponse.BeginArray("result"sv); + for (const IoBuffer& Value : CacheValues) + { + if (Value) + { + BatchResponse << CbObjectView(Value.Data()); + } + else + { + BatchResponse.AddNull(); } } - BatchResponse.EndArray(); + + CbPackage Package; Package.SetObject(BatchResponse.Save()); - + + for (const IoBuffer& Payload : Payloads) + { + Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Payload)))); + } + BinaryWriter MemStream; Package.Save(MemStream); - - Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kCbPackage, IoBuffer(IoBuffer::Wrap, MemStream.GetData(), MemStream.GetSize())); + + Request.WriteResponse(HttpResponseCode::OK, + HttpContentType::kCbPackage, + IoBuffer(IoBuffer::Wrap, MemStream.GetData(), MemStream.GetSize())); } break; default: -- cgit v1.2.3 From 4f503210dca72fdaeee61693626ef6085e93e030 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Mon, 8 Nov 2021 16:00:10 +0100 Subject: Added batched get chunk(s). --- zenserver/cache/structuredcache.cpp | 353 +++++++++++++++++++++++++----------- 1 file changed, 249 insertions(+), 104 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 59cc74d53..a1b0e1549 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -231,8 +231,8 @@ HttpStructuredCacheService::HandleGetCacheRecord(zen::HttpServerRequest& Request if (ValidCount != AttachmentCount) { - Success = false; - ZEN_WARN("GET - '{}/{}' '{}' FAILED, found '{}' of '{}' attachments", + // Success = false; + ZEN_WARN("GET - '{}/{}' '{}' is partial, found '{}' of '{}' attachments", Ref.BucketSegment, Ref.HashKey, ToString(AcceptType), @@ -554,12 +554,12 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request } }); - const bool AttachmentsValid = ValidAttachments.size() == Attachments.size(); + const bool IsPartialCacheRecord = ValidAttachments.size() != Attachments.size(); - if (!AttachmentsValid) - { - return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid attachments"sv); - } + // if (!AttachmentsValid) + //{ + // return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid attachments"sv); + //} ZEN_DEBUG("PUT - '{}/{}' {} '{}', {}/{} new attachments", Ref.BucketSegment, @@ -574,7 +574,7 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, {.Value = CacheRecord.GetBuffer().AsIoBuffer()}); - if (StoreUpstream) + if (StoreUpstream && !IsPartialCacheRecord) { ZEN_ASSERT(m_UpstreamCache); auto Result = m_UpstreamCache->EnqueueUpstream({.Type = ZenContentType::kCbPackage, @@ -786,15 +786,11 @@ HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request, { using namespace fmt::literals; - 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); - switch (auto Verb = Request.RequestVerb()) { using enum HttpVerb; - case kGet: + case kPost: { const HttpContentType ContentType = Request.RequestContentType(); const HttpContentType AcceptType = Request.AcceptContentType(); @@ -807,122 +803,271 @@ HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request, CbObject BatchRequest = zen::LoadCompactBinaryObject(Request.ReadPayload()); const std::string_view Method = BatchRequest["method"sv].AsString(); - if (Method != "getcacherecords"sv) + if (Method == "get-cache-records"sv) { - return Request.WriteResponse(HttpResponseCode::BadRequest, - HttpContentType::kText, - "Invalid method '{}'"_format(Method)); + HandleBatchGetCacheRecords(Request, BatchRequest, Policy); } + else if (Method == "get-cache-chunks"sv) + { + HandleBatchGetCacheChunks(Request, BatchRequest, Policy); + } + else + { + Request.WriteResponse(HttpResponseCode::BadRequest); + } + } + break; + default: + Request.WriteResponse(HttpResponseCode::BadRequest); + break; + } +} - CbObjectView Params = BatchRequest["params"sv].AsObjectView(); +void +HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& Request, CbObjectView BatchRequest, CachePolicy Policy) +{ + using namespace fmt::literals; - std::vector CacheKeys; - std::vector CacheValues; - std::vector Payloads; - std::vector Missing; + 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); - for (CbFieldView QueryView : Params["cachekeys"sv]) - { - CbObjectView Query = QueryView.AsObjectView(); - CacheKeys.push_back(CacheKey::Create(Query["bucket"sv].AsString(), Query["key"sv].AsHash())); - } + const std::string_view Method = BatchRequest["method"sv].AsString(); + ZEN_ASSERT(Method == "get-cache-records"sv); - CacheValues.resize(CacheKeys.size()); + CbObjectView Params = BatchRequest["params"sv].AsObjectView(); - for (size_t Idx = 0; const CacheKey& Key : CacheKeys) - { - ZenCacheValue CacheValue; - if (m_CacheStore.Get(Key.Bucket, Key.Hash, CacheValue)) - { - CbObjectView CacheRecord(CacheValue.Value.Data()); + std::vector CacheKeys; + std::vector CacheValues; + std::vector Payloads; + std::vector Missing; - if (!SkipAttachments) - { - CacheRecord.IterateAttachments([this, &Payloads](CbFieldView AttachmentHash) { - if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash())) - { - Payloads.push_back(Chunk); - } - }); - } + for (CbFieldView QueryView : Params["cachekeys"sv]) + { + CbObjectView Query = QueryView.AsObjectView(); + CacheKeys.push_back(CacheKey::Create(Query["bucket"sv].AsString(), Query["hash"sv].AsHash())); + } - CacheValues[Idx] = CacheValue.Value; - } - else + CacheValues.resize(CacheKeys.size()); + + for (size_t Idx = 0; const CacheKey& Key : CacheKeys) + { + ZenCacheValue CacheValue; + if (m_CacheStore.Get(Key.Bucket, Key.Hash, CacheValue)) + { + CbObjectView CacheRecord(CacheValue.Value.Data()); + + if (!SkipAttachments) + { + CacheRecord.IterateAttachments([this, &Payloads](CbFieldView AttachmentHash) { + if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash())) { - Missing.push_back(Idx); + Payloads.push_back(Chunk); } + }); + } - ++Idx; - } + CacheValues[Idx] = CacheValue.Value; + } + else + { + Missing.push_back(Idx); + } + + ++Idx; + } - if (QueryUpstream) + if (!Missing.empty() && QueryUpstream) + { + auto UpstreamResult = m_UpstreamCache->GetCacheRecords( + CacheKeys, + Missing, + [this, &CacheValues, &Payloads, SkipAttachments](size_t KeyIndex, IoBuffer UpstreamValue) { + CbPackage UpstreamPackage; + if (UpstreamValue && UpstreamPackage.TryLoad(UpstreamValue)) { - auto UpstreamResult = m_UpstreamCache->GetCacheRecords( - CacheKeys, - Missing, - [this, &CacheValues, &Payloads, SkipAttachments](size_t KeyIndex, IoBuffer UpstreamValue) { - CbPackage UpstreamPackage; - if (UpstreamValue && UpstreamPackage.TryLoad(UpstreamValue)) + CbObjectView CacheRecord = UpstreamPackage.GetObject(); + + CacheRecord.IterateAttachments([&](CbFieldView AttachmentHash) { + if (const CbAttachment* Attachment = UpstreamPackage.FindAttachment(AttachmentHash.AsHash())) + { + if (CompressedBuffer Chunk = Attachment->AsCompressedBinary()) { - CbObjectView CacheRecord = UpstreamPackage.GetObject(); - - CacheRecord.IterateAttachments([&](CbFieldView AttachmentHash) { - if (const CbAttachment* Attachment = UpstreamPackage.FindAttachment(AttachmentHash.AsHash())) - { - if (CompressedBuffer Chunk = Attachment->AsCompressedBinary()) - { - m_CidStore.AddChunk(Chunk); - - if (!SkipAttachments) - { - Payloads.push_back(Chunk.GetCompressed().Flatten().AsIoBuffer()); - } - } - } - }); - - CacheValues[KeyIndex] = IoBufferBuilder::MakeCloneFromMemory(CacheRecord.GetView()); + m_CidStore.AddChunk(Chunk); + + if (!SkipAttachments) + { + Payloads.push_back(Chunk.GetCompressed().Flatten().AsIoBuffer()); + } } - }); + } + }); + + CacheValues[KeyIndex] = IoBufferBuilder::MakeCloneFromMemory(CacheRecord.GetView()); } + }); + } - CbObjectWriter BatchResponse; + CbObjectWriter BatchResponse; - BatchResponse.BeginArray("result"sv); - for (const IoBuffer& Value : CacheValues) - { - if (Value) - { - BatchResponse << CbObjectView(Value.Data()); - } - else - { - BatchResponse.AddNull(); - } - } - BatchResponse.EndArray(); + BatchResponse.BeginArray("result"sv); + for (const IoBuffer& Value : CacheValues) + { + if (Value) + { + CbObjectView Record(Value.Data()); + BatchResponse << Record; + } + else + { + BatchResponse.AddNull(); + } + } + BatchResponse.EndArray(); - CbPackage Package; - Package.SetObject(BatchResponse.Save()); + CbPackage Package; + Package.SetObject(BatchResponse.Save()); - for (const IoBuffer& Payload : Payloads) - { - Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Payload)))); - } + for (const IoBuffer& Payload : Payloads) + { + Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Payload)))); + } + + BinaryWriter MemStream; + Package.Save(MemStream); + + Request.WriteResponse(HttpResponseCode::OK, + HttpContentType::kCbPackage, + IoBuffer(IoBuffer::Wrap, MemStream.GetData(), MemStream.GetSize())); +} + +void +HttpStructuredCacheService::HandleBatchGetCacheChunks(zen::HttpServerRequest& Request, CbObjectView BatchRequest, CachePolicy Policy) +{ + using namespace fmt::literals; - BinaryWriter MemStream; - Package.Save(MemStream); + 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); + + const std::string_view Method = BatchRequest["method"sv].AsString(); + ZEN_ASSERT(Method == "get-cache-chunks"sv); - Request.WriteResponse(HttpResponseCode::OK, - HttpContentType::kCbPackage, - IoBuffer(IoBuffer::Wrap, MemStream.GetData(), MemStream.GetSize())); + CbObjectView Params = BatchRequest["params"sv].AsObjectView(); + + const auto GetChunkIdFromPayloadId = [](CbObjectView Record, const Oid& PayloadId) -> IoHash { + if (CbObjectView ValueObject = Record["Value"].AsObjectView()) + { + const Oid Id = ValueObject["Id"].AsObjectId(); + if (Id == PayloadId) + { + return ValueObject["RawHash"sv].AsHash(); } - break; - default: - Request.WriteResponse(HttpResponseCode::BadRequest); - break; + } + + for (CbFieldView AttachmentView : Record["Attachments"sv]) + { + CbObjectView AttachmentObject = AttachmentView.AsObjectView(); + const Oid Id = AttachmentObject["Id"].AsObjectId(); + + if (Id == PayloadId) + { + return AttachmentObject["RawHash"sv].AsHash(); + } + } + + return IoHash::Zero; + }; + + std::vector CacheChunks; + std::vector ChunkPolicies; + std::vector Missing; + + for (CbFieldView ChunkView : Params["cachechunks"sv]) + { + CbObjectView Chunk = ChunkView.AsObjectView(); + CbObjectView CacheKeyObject = Chunk["key"sv].AsObjectView(); + const CacheKey Key = CacheKey::Create(CacheKeyObject["bucket"sv].AsString(), CacheKeyObject["hash"sv].AsHash()); + const Oid PayloadId = Chunk["id"sv].AsObjectId(); + const uint64_t RawOffset = Chunk["rawoffset"sv].AsUInt64(); + const uint64_t RawSize = Chunk["rawsize"sv].AsUInt64(); + const uint32_t ChunkPolicy = Chunk["policy"sv].AsUInt32(); + + IoHash ChunkId = IoHash::Zero; + + ZenCacheValue CacheValue; + if (m_CacheStore.Get(Key.Bucket, Key.Hash, CacheValue)) + { + ChunkId = GetChunkIdFromPayloadId(CbObjectView(CacheValue.Value.Data()), PayloadId); + } + + CacheChunks.emplace_back(Key, ChunkId, RawOffset, RawSize); + ChunkPolicies.emplace_back(static_cast(ChunkPolicy)); + } + + if (CacheChunks.empty()) + { + return Request.WriteResponse(HttpResponseCode::BadRequest); + } + + std::vector Chunks; + Chunks.resize(CacheChunks.size()); + + for (size_t Idx = 0; CacheChunk & CacheChunk : CacheChunks) + { + if (IoBuffer Chunk = m_CidStore.FindChunkByCid(CacheChunk.Id)) + { + ZEN_DEBUG("HIT - '{}/{}/{}' {} '{}' ({})", + CacheChunk.Key.Bucket, + CacheChunk.Key.Hash, + CacheChunk.Id, + NiceBytes(Chunk.Size()), + ToString(Chunk.GetContentType()), + "LOCAL"); + + Chunks[Idx] = Chunk; + } + else + { + ZEN_DEBUG("MISS - '{}/{}/{}' '{}'", + CacheChunk.Key.Bucket, + CacheChunk.Key.Hash, + CacheChunk.Id, + ToString(HttpContentType::kCompressedBinary)); + + CacheChunk.Id = IoHash::Zero; + Missing.push_back(Idx); + } + ++Idx; + } + + CbPackage Package; + CbObjectWriter BatchResponse; + + BatchResponse.BeginArray("result"sv); + + for (size_t Idx = 0; Idx < Chunks.size(); ++Idx) + { + if (Chunks[Idx]) + { + BatchResponse << CacheChunks[Idx].Id; + Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(std::move(Chunks[Idx]))))); + } + else + { + BatchResponse << IoHash::Zero; + } } + BatchResponse.EndArray(); + + Package.SetObject(BatchResponse.Save()); + + BinaryWriter MemStream; + Package.Save(MemStream); + + Request.WriteResponse(HttpResponseCode::OK, + HttpContentType::kCbPackage, + IoBuffer(IoBuffer::Wrap, MemStream.GetData(), MemStream.GetSize())); } void -- cgit v1.2.3 From e0d54396fa3ba0f5466a4ea1f2810721c18fa55f Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Tue, 9 Nov 2021 13:20:00 +0100 Subject: Sort cache keys when resolving payload ID's. --- zenserver/cache/structuredcache.cpp | 156 +++++++++++++++++++++++++++--------- 1 file changed, 117 insertions(+), 39 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index a1b0e1549..decad2f04 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -809,7 +809,7 @@ HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request, } else if (Method == "get-cache-chunks"sv) { - HandleBatchGetCacheChunks(Request, BatchRequest, Policy); + HandleBatchGetCachePayloads(Request, BatchRequest, Policy); } else { @@ -848,6 +848,11 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R CacheKeys.push_back(CacheKey::Create(Query["bucket"sv].AsString(), Query["hash"sv].AsHash())); } + if (CacheKeys.empty()) + { + return Request.WriteResponse(HttpResponseCode::BadRequest); + } + CacheValues.resize(CacheKeys.size()); for (size_t Idx = 0; const CacheKey& Key : CacheKeys) @@ -867,7 +872,14 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R }); } + ZEN_DEBUG("HIT - '{}/{}' {} '{}' (LOCAL)", + Key.Bucket, + Key.Hash, + NiceBytes(CacheValue.Value.Size()), + ToString(CacheValue.Value.GetContentType())); + CacheValues[Idx] = CacheValue.Value; + m_CacheStats.HitCount++; } else { @@ -882,8 +894,9 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R auto UpstreamResult = m_UpstreamCache->GetCacheRecords( CacheKeys, Missing, - [this, &CacheValues, &Payloads, SkipAttachments](size_t KeyIndex, IoBuffer UpstreamValue) { - CbPackage UpstreamPackage; + [this, &CacheKeys, &CacheValues, &Payloads, SkipAttachments](size_t KeyIndex, IoBuffer UpstreamValue) { + const CacheKey& Key = CacheKeys[KeyIndex]; + CbPackage UpstreamPackage; if (UpstreamValue && UpstreamPackage.TryLoad(UpstreamValue)) { CbObjectView CacheRecord = UpstreamPackage.GetObject(); @@ -903,9 +916,25 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R } }); + ZEN_DEBUG("HIT - '{}/{}' {} '{}' (UPSTREAM)", + Key.Bucket, + Key.Hash, + NiceBytes(UpstreamValue.Size()), + ToString(UpstreamValue.GetContentType())); + CacheValues[KeyIndex] = IoBufferBuilder::MakeCloneFromMemory(CacheRecord.GetView()); + m_CacheStats.UpstreamHitCount++; } }); + + Missing = std::move(UpstreamResult.Missing); + } + + for (size_t Idx : Missing) + { + const CacheKey& Key = CacheKeys[Idx]; + ZEN_DEBUG("MISS - '{}/{}'", Key.Bucket, Key.Hash); + m_CacheStats.MissCount++; } CbObjectWriter BatchResponse; @@ -942,19 +971,10 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R } void -HttpStructuredCacheService::HandleBatchGetCacheChunks(zen::HttpServerRequest& Request, CbObjectView BatchRequest, CachePolicy Policy) +HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& Request, CbObjectView BatchRequest, CachePolicy Policy) { using namespace fmt::literals; - 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); - - const std::string_view Method = BatchRequest["method"sv].AsString(); - ZEN_ASSERT(Method == "get-cache-chunks"sv); - - CbObjectView Params = BatchRequest["params"sv].AsObjectView(); - const auto GetChunkIdFromPayloadId = [](CbObjectView Record, const Oid& PayloadId) -> IoHash { if (CbObjectView ValueObject = Record["Value"].AsObjectView()) { @@ -979,68 +999,126 @@ HttpStructuredCacheService::HandleBatchGetCacheChunks(zen::HttpServerRequest& Re return IoHash::Zero; }; - std::vector CacheChunks; - std::vector ChunkPolicies; - std::vector Missing; + 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); + + const std::string_view Method = BatchRequest["method"sv].AsString(); + ZEN_ASSERT(Method == "get-cache-chunks"sv); + + CbObjectView Params = BatchRequest["params"sv].AsObjectView(); + + std::vector ChunkRequests; + std::vector Missing; - for (CbFieldView ChunkView : Params["cachechunks"sv]) + for (CbFieldView ChunkView : Params["chunkrequests"sv]) { CbObjectView Chunk = ChunkView.AsObjectView(); CbObjectView CacheKeyObject = Chunk["key"sv].AsObjectView(); const CacheKey Key = CacheKey::Create(CacheKeyObject["bucket"sv].AsString(), CacheKeyObject["hash"sv].AsHash()); - const Oid PayloadId = Chunk["id"sv].AsObjectId(); + const IoHash ChunkId = IoHash::Zero; + const Oid PayloadId = Chunk["payloadid"sv].AsObjectId(); const uint64_t RawOffset = Chunk["rawoffset"sv].AsUInt64(); const uint64_t RawSize = Chunk["rawsize"sv].AsUInt64(); const uint32_t ChunkPolicy = Chunk["policy"sv].AsUInt32(); - IoHash ChunkId = IoHash::Zero; + ChunkRequests.emplace_back(Key, ChunkId, PayloadId, RawOffset, RawSize, static_cast(ChunkPolicy)); + } - ZenCacheValue CacheValue; - if (m_CacheStore.Get(Key.Bucket, Key.Hash, CacheValue)) + std::stable_sort(ChunkRequests.begin(), ChunkRequests.end()); + + CacheKey CurrentKey = CacheKey::Empty; + IoBuffer CurrentRecordBuffer; + + for (CacheChunkRequest& ChunkRequest : ChunkRequests) + { + if (ChunkRequest.Key != CurrentKey) { - ChunkId = GetChunkIdFromPayloadId(CbObjectView(CacheValue.Value.Data()), PayloadId); + CurrentKey = ChunkRequest.Key; + + ZenCacheValue CacheValue; + if (m_CacheStore.Get(ChunkRequest.Key.Bucket, ChunkRequest.Key.Hash, CacheValue)) + { + CurrentRecordBuffer = CacheValue.Value; + } } - CacheChunks.emplace_back(Key, ChunkId, RawOffset, RawSize); - ChunkPolicies.emplace_back(static_cast(ChunkPolicy)); + if (CurrentRecordBuffer) + { + ChunkRequest.ChunkId = GetChunkIdFromPayloadId(CbObjectView(CurrentRecordBuffer.GetData()), ChunkRequest.PayloadId); + } } - if (CacheChunks.empty()) + if (ChunkRequests.empty()) { return Request.WriteResponse(HttpResponseCode::BadRequest); } std::vector Chunks; - Chunks.resize(CacheChunks.size()); + Chunks.resize(ChunkRequests.size()); - for (size_t Idx = 0; CacheChunk & CacheChunk : CacheChunks) + for (size_t Idx = 0; const CacheChunkRequest& ChunkRequest : ChunkRequests) { - if (IoBuffer Chunk = m_CidStore.FindChunkByCid(CacheChunk.Id)) + if (IoBuffer Chunk = m_CidStore.FindChunkByCid(ChunkRequest.ChunkId)) { ZEN_DEBUG("HIT - '{}/{}/{}' {} '{}' ({})", - CacheChunk.Key.Bucket, - CacheChunk.Key.Hash, - CacheChunk.Id, + ChunkRequest.Key.Bucket, + ChunkRequest.Key.Hash, + ChunkRequest.ChunkId, NiceBytes(Chunk.Size()), ToString(Chunk.GetContentType()), "LOCAL"); Chunks[Idx] = Chunk; + m_CacheStats.HitCount++; } else { - ZEN_DEBUG("MISS - '{}/{}/{}' '{}'", - CacheChunk.Key.Bucket, - CacheChunk.Key.Hash, - CacheChunk.Id, - ToString(HttpContentType::kCompressedBinary)); - - CacheChunk.Id = IoHash::Zero; Missing.push_back(Idx); } ++Idx; } + if (!Missing.empty() && QueryUpstream) + { + auto UpstreamResult = m_UpstreamCache->GetCachePayloads( + ChunkRequests, + Missing, + [this, &ChunkRequests, &Chunks](size_t ChunkIndex, IoBuffer UpstreamValue) { + const CacheChunkRequest& ChunkRequest = ChunkRequests[ChunkIndex]; + + if (CompressedBuffer CompressedChunk = CompressedBuffer::FromCompressed(SharedBuffer(UpstreamValue))) + { + auto InsertResult = m_CidStore.AddChunk(CompressedChunk); + IoBuffer Chunk = CompressedChunk.GetCompressed().Flatten().AsIoBuffer(); + + ZEN_DEBUG("HIT - '{}/{}/{}' {} '{}' ({})", + ChunkRequest.Key.Bucket, + ChunkRequest.Key.Hash, + ChunkRequest.ChunkId, + NiceBytes(Chunk.GetSize()), + ToString(Chunk.GetContentType()), + "UPSTREAM"); + + Chunks[ChunkIndex] = Chunk; + m_CacheStats.UpstreamHitCount++; + } + else + { + ZEN_WARN("got uncompressed upstream cache payload"); + } + }); + + Missing = std::move(UpstreamResult.Missing); + } + + for (size_t Idx : Missing) + { + const CacheChunkRequest& ChunkRequest = ChunkRequests[Idx]; + ZEN_DEBUG("MISS - '{}/{}/{}'", ChunkRequest.Key.Bucket, ChunkRequest.Key.Hash, ChunkRequest.ChunkId); + m_CacheStats.MissCount++; + } + CbPackage Package; CbObjectWriter BatchResponse; @@ -1050,7 +1128,7 @@ HttpStructuredCacheService::HandleBatchGetCacheChunks(zen::HttpServerRequest& Re { if (Chunks[Idx]) { - BatchResponse << CacheChunks[Idx].Id; + BatchResponse << ChunkRequests[Idx].ChunkId; Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(std::move(Chunks[Idx]))))); } else -- cgit v1.2.3 From 424be141e88b04b4de7ab5def2c29b03f5f72d48 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Wed, 10 Nov 2021 08:47:57 +0100 Subject: Handle cache record policy. --- zenserver/cache/structuredcache.cpp | 40 ++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index decad2f04..073192c12 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -114,9 +114,7 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request) if (Key == "$batch") { - const auto QueryParams = Request.GetQueryParams(); - CachePolicy Policy = ParseCachePolicy(QueryParams); - return HandleBatchRequest(Request, Policy); + return HandleBatchRequest(Request); } if (std::all_of(begin(Key), end(Key), [](const char c) { return std::isalnum(c); })) @@ -782,10 +780,8 @@ HttpStructuredCacheService::ValidateKeyUri(HttpServerRequest& Request, CacheRef& } void -HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request, CachePolicy Policy) +HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request) { - using namespace fmt::literals; - switch (auto Verb = Request.RequestVerb()) { using enum HttpVerb; @@ -805,11 +801,11 @@ HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request, if (Method == "get-cache-records"sv) { - HandleBatchGetCacheRecords(Request, BatchRequest, Policy); + HandleBatchGetCacheRecords(Request, BatchRequest); } else if (Method == "get-cache-chunks"sv) { - HandleBatchGetCachePayloads(Request, BatchRequest, Policy); + HandleBatchGetCachePayloads(Request, BatchRequest); } else { @@ -824,19 +820,21 @@ HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request, } void -HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& Request, CbObjectView BatchRequest, CachePolicy Policy) +HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& Request, CbObjectView BatchRequest) { using namespace fmt::literals; - 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); - const std::string_view Method = BatchRequest["method"sv].AsString(); ZEN_ASSERT(Method == "get-cache-records"sv); CbObjectView Params = BatchRequest["params"sv].AsObjectView(); + CacheRecordPolicy Policy; + CacheRecordPolicy::FromCompactBinary(Params["policy"sv].AsObjectView(), Policy); + + const bool SkipAttachments = (Policy.GetRecordPolicy() & CachePolicy::SkipAttachments) == CachePolicy::SkipAttachments; + const bool QueryUpstream = m_UpstreamCache && ((Policy.GetRecordPolicy() & CachePolicy::QueryRemote) == CachePolicy::QueryRemote); + std::vector CacheKeys; std::vector CacheValues; std::vector Payloads; @@ -855,6 +853,11 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R CacheValues.resize(CacheKeys.size()); + if (!SkipAttachments) + { + Payloads.reserve(CacheKeys.size()); + } + for (size_t Idx = 0; const CacheKey& Key : CacheKeys) { ZenCacheValue CacheValue; @@ -971,7 +974,7 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R } void -HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& Request, CbObjectView BatchRequest, CachePolicy Policy) +HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& Request, CbObjectView BatchRequest) { using namespace fmt::literals; @@ -999,15 +1002,16 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& return IoHash::Zero; }; - 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); - const std::string_view Method = BatchRequest["method"sv].AsString(); ZEN_ASSERT(Method == "get-cache-chunks"sv); CbObjectView Params = BatchRequest["params"sv].AsObjectView(); + CacheRecordPolicy Policy; + CacheRecordPolicy::FromCompactBinary(Params["policy"sv].AsObjectView(), Policy); + + const bool QueryUpstream = m_UpstreamCache && ((Policy.GetRecordPolicy() & CachePolicy::QueryRemote) == CachePolicy::QueryRemote); + std::vector ChunkRequests; std::vector Missing; -- cgit v1.2.3 From 6b5748c8424cdac3c7a39ef87a9bc33ffa69256f Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Wed, 10 Nov 2021 10:58:30 +0100 Subject: Changed RPC keys to camel case. --- zenserver/cache/structuredcache.cpp | 76 ++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 073192c12..45f626ff5 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -797,13 +797,13 @@ HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request) } CbObject BatchRequest = zen::LoadCompactBinaryObject(Request.ReadPayload()); - const std::string_view Method = BatchRequest["method"sv].AsString(); + const std::string_view Method = BatchRequest["Method"sv].AsString(); - if (Method == "get-cache-records"sv) + if (Method == "GetCacheRecords"sv) { HandleBatchGetCacheRecords(Request, BatchRequest); } - else if (Method == "get-cache-chunks"sv) + else if (Method == "GetCachePayloads"sv) { HandleBatchGetCachePayloads(Request, BatchRequest); } @@ -824,13 +824,13 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R { using namespace fmt::literals; - const std::string_view Method = BatchRequest["method"sv].AsString(); - ZEN_ASSERT(Method == "get-cache-records"sv); + const std::string_view Method = BatchRequest["Method"sv].AsString(); + ZEN_ASSERT(Method == "GetCacheRecords"sv); - CbObjectView Params = BatchRequest["params"sv].AsObjectView(); + CbObjectView Params = BatchRequest["Params"sv].AsObjectView(); CacheRecordPolicy Policy; - CacheRecordPolicy::FromCompactBinary(Params["policy"sv].AsObjectView(), Policy); + CacheRecordPolicy::FromCompactBinary(Params["Policy"sv].AsObjectView(), Policy); const bool SkipAttachments = (Policy.GetRecordPolicy() & CachePolicy::SkipAttachments) == CachePolicy::SkipAttachments; const bool QueryUpstream = m_UpstreamCache && ((Policy.GetRecordPolicy() & CachePolicy::QueryRemote) == CachePolicy::QueryRemote); @@ -840,10 +840,10 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R std::vector Payloads; std::vector Missing; - for (CbFieldView QueryView : Params["cachekeys"sv]) + for (CbFieldView QueryView : Params["CacheKeys"sv]) { CbObjectView Query = QueryView.AsObjectView(); - CacheKeys.push_back(CacheKey::Create(Query["bucket"sv].AsString(), Query["hash"sv].AsHash())); + CacheKeys.push_back(CacheKey::Create(Query["Bucket"sv].AsString(), Query["Hash"sv].AsHash())); } if (CacheKeys.empty()) @@ -858,7 +858,7 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R Payloads.reserve(CacheKeys.size()); } - for (size_t Idx = 0; const CacheKey& Key : CacheKeys) + for (size_t KeyIndex = 0; const CacheKey& Key : CacheKeys) { ZenCacheValue CacheValue; if (m_CacheStore.Get(Key.Bucket, Key.Hash, CacheValue)) @@ -881,15 +881,15 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R NiceBytes(CacheValue.Value.Size()), ToString(CacheValue.Value.GetContentType())); - CacheValues[Idx] = CacheValue.Value; + CacheValues[KeyIndex] = CacheValue.Value; m_CacheStats.HitCount++; } else { - Missing.push_back(Idx); + Missing.push_back(KeyIndex); } - ++Idx; + ++KeyIndex; } if (!Missing.empty() && QueryUpstream) @@ -933,16 +933,16 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R Missing = std::move(UpstreamResult.Missing); } - for (size_t Idx : Missing) + for (size_t KeyIndex : Missing) { - const CacheKey& Key = CacheKeys[Idx]; + const CacheKey& Key = CacheKeys[KeyIndex]; ZEN_DEBUG("MISS - '{}/{}'", Key.Bucket, Key.Hash); m_CacheStats.MissCount++; } CbObjectWriter BatchResponse; - BatchResponse.BeginArray("result"sv); + BatchResponse.BeginArray("Result"sv); for (const IoBuffer& Value : CacheValues) { if (Value) @@ -1002,29 +1002,29 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& return IoHash::Zero; }; - const std::string_view Method = BatchRequest["method"sv].AsString(); - ZEN_ASSERT(Method == "get-cache-chunks"sv); + const std::string_view Method = BatchRequest["Method"sv].AsString(); + ZEN_ASSERT(Method == "GetCachePayloads"sv); - CbObjectView Params = BatchRequest["params"sv].AsObjectView(); + CbObjectView Params = BatchRequest["Params"sv].AsObjectView(); CacheRecordPolicy Policy; - CacheRecordPolicy::FromCompactBinary(Params["policy"sv].AsObjectView(), Policy); + CacheRecordPolicy::FromCompactBinary(Params["Policy"sv].AsObjectView(), Policy); const bool QueryUpstream = m_UpstreamCache && ((Policy.GetRecordPolicy() & CachePolicy::QueryRemote) == CachePolicy::QueryRemote); std::vector ChunkRequests; std::vector Missing; - for (CbFieldView ChunkView : Params["chunkrequests"sv]) + for (CbFieldView ChunkView : Params["ChunkRequests"sv]) { CbObjectView Chunk = ChunkView.AsObjectView(); - CbObjectView CacheKeyObject = Chunk["key"sv].AsObjectView(); - const CacheKey Key = CacheKey::Create(CacheKeyObject["bucket"sv].AsString(), CacheKeyObject["hash"sv].AsHash()); + CbObjectView CacheKeyObject = Chunk["Key"sv].AsObjectView(); + const CacheKey Key = CacheKey::Create(CacheKeyObject["Bucket"sv].AsString(), CacheKeyObject["Hash"sv].AsHash()); const IoHash ChunkId = IoHash::Zero; - const Oid PayloadId = Chunk["payloadid"sv].AsObjectId(); - const uint64_t RawOffset = Chunk["rawoffset"sv].AsUInt64(); - const uint64_t RawSize = Chunk["rawsize"sv].AsUInt64(); - const uint32_t ChunkPolicy = Chunk["policy"sv].AsUInt32(); + const Oid PayloadId = Chunk["PayloadId"sv].AsObjectId(); + const uint64_t RawOffset = Chunk["RawoffSet"sv].AsUInt64(); + const uint64_t RawSize = Chunk["RawSize"sv].AsUInt64(); + const uint32_t ChunkPolicy = Chunk["Policy"sv].AsUInt32(); ChunkRequests.emplace_back(Key, ChunkId, PayloadId, RawOffset, RawSize, static_cast(ChunkPolicy)); } @@ -1061,7 +1061,7 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& std::vector Chunks; Chunks.resize(ChunkRequests.size()); - for (size_t Idx = 0; const CacheChunkRequest& ChunkRequest : ChunkRequests) + for (size_t RequestIndex = 0; const CacheChunkRequest& ChunkRequest : ChunkRequests) { if (IoBuffer Chunk = m_CidStore.FindChunkByCid(ChunkRequest.ChunkId)) { @@ -1073,14 +1073,14 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& ToString(Chunk.GetContentType()), "LOCAL"); - Chunks[Idx] = Chunk; + Chunks[RequestIndex] = Chunk; m_CacheStats.HitCount++; } else { - Missing.push_back(Idx); + Missing.push_back(RequestIndex); } - ++Idx; + ++RequestIndex; } if (!Missing.empty() && QueryUpstream) @@ -1116,9 +1116,9 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& Missing = std::move(UpstreamResult.Missing); } - for (size_t Idx : Missing) + for (size_t RequestIndex : Missing) { - const CacheChunkRequest& ChunkRequest = ChunkRequests[Idx]; + const CacheChunkRequest& ChunkRequest = ChunkRequests[RequestIndex]; ZEN_DEBUG("MISS - '{}/{}/{}'", ChunkRequest.Key.Bucket, ChunkRequest.Key.Hash, ChunkRequest.ChunkId); m_CacheStats.MissCount++; } @@ -1126,14 +1126,14 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& CbPackage Package; CbObjectWriter BatchResponse; - BatchResponse.BeginArray("result"sv); + BatchResponse.BeginArray("Result"sv); - for (size_t Idx = 0; Idx < Chunks.size(); ++Idx) + for (size_t ChunkIndex = 0; ChunkIndex < Chunks.size(); ++ChunkIndex) { - if (Chunks[Idx]) + if (Chunks[ChunkIndex]) { - BatchResponse << ChunkRequests[Idx].ChunkId; - Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(std::move(Chunks[Idx]))))); + BatchResponse << ChunkRequests[ChunkIndex].ChunkId; + Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(std::move(Chunks[ChunkIndex]))))); } else { -- cgit v1.2.3 From 39e064c35abd6bc8d2d32b9bb99b5805d1d1e78c Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Wed, 10 Nov 2021 14:58:04 +0100 Subject: Honor cache policy. --- zenserver/cache/structuredcache.cpp | 72 ++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 24 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 45f626ff5..de2fcb27c 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -833,11 +833,12 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R CacheRecordPolicy::FromCompactBinary(Params["Policy"sv].AsObjectView(), Policy); const bool SkipAttachments = (Policy.GetRecordPolicy() & CachePolicy::SkipAttachments) == CachePolicy::SkipAttachments; - const bool QueryUpstream = m_UpstreamCache && ((Policy.GetRecordPolicy() & CachePolicy::QueryRemote) == CachePolicy::QueryRemote); + const bool QueryRemote = m_UpstreamCache && ((Policy.GetRecordPolicy() & CachePolicy::QueryRemote) == CachePolicy::QueryRemote); std::vector CacheKeys; std::vector CacheValues; std::vector Payloads; + std::vector UpstreamRequests; std::vector Missing; for (CbFieldView QueryView : Params["CacheKeys"sv]) @@ -884,6 +885,10 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R CacheValues[KeyIndex] = CacheValue.Value; m_CacheStats.HitCount++; } + else if (QueryRemote) + { + UpstreamRequests.push_back(KeyIndex); + } else { Missing.push_back(KeyIndex); @@ -892,11 +897,11 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R ++KeyIndex; } - if (!Missing.empty() && QueryUpstream) + if (!UpstreamRequests.empty() && m_UpstreamCache) { auto UpstreamResult = m_UpstreamCache->GetCacheRecords( CacheKeys, - Missing, + UpstreamRequests, [this, &CacheKeys, &CacheValues, &Payloads, SkipAttachments](size_t KeyIndex, IoBuffer UpstreamValue) { const CacheKey& Key = CacheKeys[KeyIndex]; CbPackage UpstreamPackage; @@ -930,7 +935,10 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R } }); - Missing = std::move(UpstreamResult.Missing); + for (size_t MissingUpstream : UpstreamResult.Missing) + { + Missing.push_back(MissingUpstream); + } } for (size_t KeyIndex : Missing) @@ -1007,12 +1015,8 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& CbObjectView Params = BatchRequest["Params"sv].AsObjectView(); - CacheRecordPolicy Policy; - CacheRecordPolicy::FromCompactBinary(Params["Policy"sv].AsObjectView(), Policy); - - const bool QueryUpstream = m_UpstreamCache && ((Policy.GetRecordPolicy() & CachePolicy::QueryRemote) == CachePolicy::QueryRemote); - std::vector ChunkRequests; + std::vector UpstreamRequests; std::vector Missing; for (CbFieldView ChunkView : Params["ChunkRequests"sv]) @@ -1063,31 +1067,46 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& for (size_t RequestIndex = 0; const CacheChunkRequest& ChunkRequest : ChunkRequests) { - if (IoBuffer Chunk = m_CidStore.FindChunkByCid(ChunkRequest.ChunkId)) + const bool QueryLocal = (ChunkRequest.Policy & CachePolicy::QueryLocal) == CachePolicy::QueryLocal; + const bool QueryRemote = (ChunkRequest.Policy & CachePolicy::QueryRemote) == CachePolicy::QueryRemote; + + if (QueryLocal) { - ZEN_DEBUG("HIT - '{}/{}/{}' {} '{}' ({})", - ChunkRequest.Key.Bucket, - ChunkRequest.Key.Hash, - ChunkRequest.ChunkId, - NiceBytes(Chunk.Size()), - ToString(Chunk.GetContentType()), - "LOCAL"); - - Chunks[RequestIndex] = Chunk; - m_CacheStats.HitCount++; + if (IoBuffer Chunk = m_CidStore.FindChunkByCid(ChunkRequest.ChunkId)) + { + ZEN_DEBUG("HIT - '{}/{}/{}' {} '{}' ({})", + ChunkRequest.Key.Bucket, + ChunkRequest.Key.Hash, + ChunkRequest.ChunkId, + NiceBytes(Chunk.Size()), + ToString(Chunk.GetContentType()), + "LOCAL"); + + Chunks[RequestIndex] = Chunk; + m_CacheStats.HitCount++; + } + else if (QueryRemote) + { + UpstreamRequests.push_back(RequestIndex); + } + else + { + Missing.push_back(RequestIndex); + } } else { - Missing.push_back(RequestIndex); + ZEN_DEBUG("SKIP - '{}/{}/{}'", ChunkRequest.Key.Bucket, ChunkRequest.Key.Hash, ChunkRequest.ChunkId); } + ++RequestIndex; } - if (!Missing.empty() && QueryUpstream) + if (!UpstreamRequests.empty() && m_UpstreamCache) { auto UpstreamResult = m_UpstreamCache->GetCachePayloads( ChunkRequests, - Missing, + UpstreamRequests, [this, &ChunkRequests, &Chunks](size_t ChunkIndex, IoBuffer UpstreamValue) { const CacheChunkRequest& ChunkRequest = ChunkRequests[ChunkIndex]; @@ -1105,6 +1124,8 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& "UPSTREAM"); Chunks[ChunkIndex] = Chunk; + + m_CacheStats.HitCount++; m_CacheStats.UpstreamHitCount++; } else @@ -1113,7 +1134,10 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& } }); - Missing = std::move(UpstreamResult.Missing); + for (size_t MissingUpstream : UpstreamResult.Missing) + { + Missing.push_back(MissingUpstream); + } } for (size_t RequestIndex : Missing) -- cgit v1.2.3 From 2c0e2ab5de21b13dcd25758ca3b96af889db7137 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Thu, 11 Nov 2021 11:19:17 +0100 Subject: Added batch API to upstream endpoints. --- zenserver/cache/structuredcache.cpp | 93 ++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 53 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index de2fcb27c..721942cc8 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -618,7 +618,7 @@ HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Reques if (QueryUpstream) { - if (auto UpstreamResult = m_UpstreamCache->GetCachePayload({{Ref.BucketSegment, Ref.HashKey}, Ref.PayloadId}); + if (auto UpstreamResult = m_UpstreamCache->GetCachePayload({Ref.BucketSegment, Ref.HashKey}, Ref.PayloadId); UpstreamResult.Success) { if (CompressedBuffer Compressed = CompressedBuffer::FromCompressed(SharedBuffer(UpstreamResult.Value))) @@ -830,7 +830,7 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R CbObjectView Params = BatchRequest["Params"sv].AsObjectView(); CacheRecordPolicy Policy; - CacheRecordPolicy::FromCompactBinary(Params["Policy"sv].AsObjectView(), Policy); + 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); @@ -899,18 +899,12 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R if (!UpstreamRequests.empty() && m_UpstreamCache) { - auto UpstreamResult = m_UpstreamCache->GetCacheRecords( - CacheKeys, - UpstreamRequests, - [this, &CacheKeys, &CacheValues, &Payloads, SkipAttachments](size_t KeyIndex, IoBuffer UpstreamValue) { - const CacheKey& Key = CacheKeys[KeyIndex]; - CbPackage UpstreamPackage; - if (UpstreamValue && UpstreamPackage.TryLoad(UpstreamValue)) + const auto OnCacheRecordGetComplete = + [this, &CacheKeys, &CacheValues, &Payloads, &Missing, SkipAttachments](CacheRecordGetCompleteParams&& Params) { + if (Params.Record) { - CbObjectView CacheRecord = UpstreamPackage.GetObject(); - - CacheRecord.IterateAttachments([&](CbFieldView AttachmentHash) { - if (const CbAttachment* Attachment = UpstreamPackage.FindAttachment(AttachmentHash.AsHash())) + Params.Record.IterateAttachments([&](CbFieldView AttachmentHash) { + if (const CbAttachment* Attachment = Params.Package.FindAttachment(AttachmentHash.AsHash())) { if (CompressedBuffer Chunk = Attachment->AsCompressedBinary()) { @@ -925,20 +919,21 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R }); ZEN_DEBUG("HIT - '{}/{}' {} '{}' (UPSTREAM)", - Key.Bucket, - Key.Hash, - NiceBytes(UpstreamValue.Size()), - ToString(UpstreamValue.GetContentType())); + Params.CacheKey.Bucket, + Params.CacheKey.Hash, + NiceBytes(Params.Record.GetView().GetSize()), + ToString(HttpContentType::kCbObject)); - CacheValues[KeyIndex] = IoBufferBuilder::MakeCloneFromMemory(CacheRecord.GetView()); + CacheValues[Params.KeyIndex] = IoBufferBuilder::MakeCloneFromMemory(Params.Record.GetView()); m_CacheStats.UpstreamHitCount++; } - }); + else + { + Missing.push_back(Params.KeyIndex); + } + }; - for (size_t MissingUpstream : UpstreamResult.Missing) - { - Missing.push_back(MissingUpstream); - } + m_UpstreamCache->GetCacheRecords(CacheKeys, UpstreamRequests, Policy, std::move(OnCacheRecordGetComplete)); } for (size_t KeyIndex : Missing) @@ -1104,40 +1099,32 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& if (!UpstreamRequests.empty() && m_UpstreamCache) { - auto UpstreamResult = m_UpstreamCache->GetCachePayloads( - ChunkRequests, - UpstreamRequests, - [this, &ChunkRequests, &Chunks](size_t ChunkIndex, IoBuffer UpstreamValue) { - const CacheChunkRequest& ChunkRequest = ChunkRequests[ChunkIndex]; - - if (CompressedBuffer CompressedChunk = CompressedBuffer::FromCompressed(SharedBuffer(UpstreamValue))) - { - auto InsertResult = m_CidStore.AddChunk(CompressedChunk); - IoBuffer Chunk = CompressedChunk.GetCompressed().Flatten().AsIoBuffer(); + const auto OnCachePayloadGetComplete = [this, &ChunkRequests, &Chunks, &Missing](CachePayloadGetCompleteParams&& Params) { + if (Params.Payload) + { + CompressedBuffer Compressed = CompressedBuffer::FromCompressed(SharedBuffer(Params.Payload)); + auto InsertResult = m_CidStore.AddChunk(Compressed); - ZEN_DEBUG("HIT - '{}/{}/{}' {} '{}' ({})", - ChunkRequest.Key.Bucket, - ChunkRequest.Key.Hash, - ChunkRequest.ChunkId, - NiceBytes(Chunk.GetSize()), - ToString(Chunk.GetContentType()), - "UPSTREAM"); + ZEN_DEBUG("HIT - '{}/{}/{}' {} '{}' ({})", + Params.Request.Key.Bucket, + Params.Request.Key.Hash, + Params.Request.ChunkId, + NiceBytes(Params.Payload.GetSize()), + ToString(Params.Payload.GetContentType()), + "UPSTREAM"); - Chunks[ChunkIndex] = Chunk; + Chunks[Params.RequestIndex] = std::move(Params.Payload); - m_CacheStats.HitCount++; - m_CacheStats.UpstreamHitCount++; - } - else - { - ZEN_WARN("got uncompressed upstream cache payload"); - } - }); + m_CacheStats.HitCount++; + m_CacheStats.UpstreamHitCount++; + } + else + { + Missing.push_back(Params.RequestIndex); + } + }; - for (size_t MissingUpstream : UpstreamResult.Missing) - { - Missing.push_back(MissingUpstream); - } + m_UpstreamCache->GetCachePayloads(ChunkRequests, UpstreamRequests, std::move(OnCachePayloadGetComplete)); } for (size_t RequestIndex : Missing) -- cgit v1.2.3 From 31ba344167677f175ec79ce7e579552a9811245d Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Thu, 11 Nov 2021 11:21:31 +0100 Subject: Format and remove unused type. --- zenserver/cache/structuredcache.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 721942cc8..632368062 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -618,8 +618,7 @@ HttpStructuredCacheService::HandleGetCachePayload(zen::HttpServerRequest& Reques if (QueryUpstream) { - if (auto UpstreamResult = m_UpstreamCache->GetCachePayload({Ref.BucketSegment, Ref.HashKey}, Ref.PayloadId); - UpstreamResult.Success) + if (auto UpstreamResult = m_UpstreamCache->GetCachePayload({Ref.BucketSegment, Ref.HashKey}, Ref.PayloadId); UpstreamResult.Success) { if (CompressedBuffer Compressed = CompressedBuffer::FromCompressed(SharedBuffer(UpstreamResult.Value))) { -- cgit v1.2.3 From 3efc2ddb02511300cd6dfe59cd89ca4338f6ec4c Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Thu, 11 Nov 2021 15:05:11 +0100 Subject: Handle batch requests asynchronously. --- zenserver/cache/structuredcache.cpp | 264 ++++++++++++++++-------------------- 1 file changed, 120 insertions(+), 144 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 632368062..10fbb3709 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -795,21 +795,22 @@ HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request) return Request.WriteResponse(HttpResponseCode::BadRequest); } - CbObject BatchRequest = zen::LoadCompactBinaryObject(Request.ReadPayload()); - const std::string_view Method = BatchRequest["Method"sv].AsString(); - - if (Method == "GetCacheRecords"sv) - { - HandleBatchGetCacheRecords(Request, BatchRequest); - } - else if (Method == "GetCachePayloads"sv) - { - HandleBatchGetCachePayloads(Request, BatchRequest); - } - else - { - Request.WriteResponse(HttpResponseCode::BadRequest); - } + Request.WriteResponseAsync( + [this, BatchRequest = zen::LoadCompactBinaryObject(Request.ReadPayload())](HttpServerRequest& AsyncRequest) { + const std::string_view Method = BatchRequest["Method"sv].AsString(); + if (Method == "GetCacheRecords"sv) + { + HandleBatchGetCacheRecords(AsyncRequest, BatchRequest); + } + else if (Method == "GetCachePayloads"sv) + { + HandleBatchGetCachePayloads(AsyncRequest, BatchRequest); + } + else + { + AsyncRequest.WriteResponse(HttpResponseCode::BadRequest); + } + }); } break; default: @@ -823,27 +824,24 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R { using namespace fmt::literals; - const std::string_view Method = BatchRequest["Method"sv].AsString(); - ZEN_ASSERT(Method == "GetCacheRecords"sv); + CbPackage BatchResponse; + CacheRecordPolicy Policy; + CbObjectView Params = BatchRequest["Params"sv].AsObjectView(); + std::vector CacheKeys; + std::vector CacheValues; + std::vector UpstreamRequests; - CbObjectView Params = BatchRequest["Params"sv].AsObjectView(); + ZEN_ASSERT(BatchRequest["Method"sv].AsString() == "GetCacheRecords"sv); - CacheRecordPolicy Policy; 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); - std::vector CacheKeys; - std::vector CacheValues; - std::vector Payloads; - std::vector UpstreamRequests; - std::vector Missing; - - for (CbFieldView QueryView : Params["CacheKeys"sv]) + for (CbFieldView KeyView : Params["CacheKeys"sv]) { - CbObjectView Query = QueryView.AsObjectView(); - CacheKeys.push_back(CacheKey::Create(Query["Bucket"sv].AsString(), Query["Hash"sv].AsHash())); + CbObjectView KeyObject = KeyView.AsObjectView(); + CacheKeys.push_back(CacheKey::Create(KeyObject["Bucket"sv].AsString(), KeyObject["Hash"sv].AsHash())); } if (CacheKeys.empty()) @@ -853,11 +851,6 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R CacheValues.resize(CacheKeys.size()); - if (!SkipAttachments) - { - Payloads.reserve(CacheKeys.size()); - } - for (size_t KeyIndex = 0; const CacheKey& Key : CacheKeys) { ZenCacheValue CacheValue; @@ -867,10 +860,10 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R if (!SkipAttachments) { - CacheRecord.IterateAttachments([this, &Payloads](CbFieldView AttachmentHash) { + CacheRecord.IterateAttachments([this, &BatchResponse](CbFieldView AttachmentHash) { if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash())) { - Payloads.push_back(Chunk); + BatchResponse.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk)))); } }); } @@ -890,7 +883,8 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R } else { - Missing.push_back(KeyIndex); + ZEN_DEBUG("MISS - '{}/{}'", Key.Bucket, Key.Hash); + m_CacheStats.MissCount++; } ++KeyIndex; @@ -899,19 +893,19 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R if (!UpstreamRequests.empty() && m_UpstreamCache) { const auto OnCacheRecordGetComplete = - [this, &CacheKeys, &CacheValues, &Payloads, &Missing, SkipAttachments](CacheRecordGetCompleteParams&& Params) { + [this, &CacheKeys, &CacheValues, &BatchResponse, SkipAttachments](CacheRecordGetCompleteParams&& Params) { if (Params.Record) { Params.Record.IterateAttachments([&](CbFieldView AttachmentHash) { if (const CbAttachment* Attachment = Params.Package.FindAttachment(AttachmentHash.AsHash())) { - if (CompressedBuffer Chunk = Attachment->AsCompressedBinary()) + if (CompressedBuffer Compressed = Attachment->AsCompressedBinary()) { - m_CidStore.AddChunk(Chunk); + m_CidStore.AddChunk(Compressed); if (!SkipAttachments) { - Payloads.push_back(Chunk.GetCompressed().Flatten().AsIoBuffer()); + BatchResponse.AddAttachment(CbAttachment(Compressed)); } } } @@ -924,51 +918,40 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R ToString(HttpContentType::kCbObject)); CacheValues[Params.KeyIndex] = IoBufferBuilder::MakeCloneFromMemory(Params.Record.GetView()); + m_CacheStats.HitCount++; m_CacheStats.UpstreamHitCount++; } else { - Missing.push_back(Params.KeyIndex); + ZEN_DEBUG("MISS - '{}/{}'", Params.CacheKey.Bucket, Params.CacheKey.Hash); + m_CacheStats.MissCount++; } }; m_UpstreamCache->GetCacheRecords(CacheKeys, UpstreamRequests, Policy, std::move(OnCacheRecordGetComplete)); } - for (size_t KeyIndex : Missing) - { - const CacheKey& Key = CacheKeys[KeyIndex]; - ZEN_DEBUG("MISS - '{}/{}'", Key.Bucket, Key.Hash); - m_CacheStats.MissCount++; - } + CbObjectWriter ResponseObject; - CbObjectWriter BatchResponse; - - BatchResponse.BeginArray("Result"sv); + ResponseObject.BeginArray("Result"sv); for (const IoBuffer& Value : CacheValues) { if (Value) { CbObjectView Record(Value.Data()); - BatchResponse << Record; + ResponseObject << Record; } else { - BatchResponse.AddNull(); + ResponseObject.AddNull(); } } - BatchResponse.EndArray(); + ResponseObject.EndArray(); - CbPackage Package; - Package.SetObject(BatchResponse.Save()); - - for (const IoBuffer& Payload : Payloads) - { - Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Payload)))); - } + BatchResponse.SetObject(ResponseObject.Save()); BinaryWriter MemStream; - Package.Save(MemStream); + BatchResponse.Save(MemStream); Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kCbPackage, @@ -980,84 +963,84 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& { using namespace fmt::literals; - const auto GetChunkIdFromPayloadId = [](CbObjectView Record, const Oid& PayloadId) -> IoHash { - if (CbObjectView ValueObject = Record["Value"].AsObjectView()) - { - const Oid Id = ValueObject["Id"].AsObjectId(); - if (Id == PayloadId) - { - return ValueObject["RawHash"sv].AsHash(); - } - } - - for (CbFieldView AttachmentView : Record["Attachments"sv]) - { - CbObjectView AttachmentObject = AttachmentView.AsObjectView(); - const Oid Id = AttachmentObject["Id"].AsObjectId(); - - if (Id == PayloadId) - { - return AttachmentObject["RawHash"sv].AsHash(); - } - } - - return IoHash::Zero; - }; - - const std::string_view Method = BatchRequest["Method"sv].AsString(); - ZEN_ASSERT(Method == "GetCachePayloads"sv); - - CbObjectView Params = BatchRequest["Params"sv].AsObjectView(); + ZEN_ASSERT(BatchRequest["Method"sv].AsString() == "GetCachePayloads"sv); std::vector ChunkRequests; std::vector UpstreamRequests; - std::vector Missing; + std::vector Chunks; + CbObjectView Params = BatchRequest["Params"sv].AsObjectView(); - for (CbFieldView ChunkView : Params["ChunkRequests"sv]) + for (CbFieldView RequestView : Params["ChunkRequests"sv]) { - CbObjectView Chunk = ChunkView.AsObjectView(); - CbObjectView CacheKeyObject = Chunk["Key"sv].AsObjectView(); - const CacheKey Key = CacheKey::Create(CacheKeyObject["Bucket"sv].AsString(), CacheKeyObject["Hash"sv].AsHash()); - const IoHash ChunkId = IoHash::Zero; - const Oid PayloadId = Chunk["PayloadId"sv].AsObjectId(); - const uint64_t RawOffset = Chunk["RawoffSet"sv].AsUInt64(); - const uint64_t RawSize = Chunk["RawSize"sv].AsUInt64(); - const uint32_t ChunkPolicy = Chunk["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 = IoHash::Zero; + 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(); ChunkRequests.emplace_back(Key, ChunkId, PayloadId, RawOffset, RawSize, static_cast(ChunkPolicy)); } - std::stable_sort(ChunkRequests.begin(), ChunkRequests.end()); + if (ChunkRequests.empty()) + { + return Request.WriteResponse(HttpResponseCode::BadRequest); + } - CacheKey CurrentKey = CacheKey::Empty; - IoBuffer CurrentRecordBuffer; + Chunks.resize(ChunkRequests.size()); - for (CacheChunkRequest& ChunkRequest : ChunkRequests) + // Try to find the uncompressed raw hash from the payload ID. { - if (ChunkRequest.Key != CurrentKey) - { - CurrentKey = ChunkRequest.Key; + const auto GetChunkIdFromPayloadId = [](CbObjectView Record, const Oid& PayloadId) -> IoHash { + if (CbObjectView ValueObject = Record["Value"].AsObjectView()) + { + const Oid Id = ValueObject["Id"].AsObjectId(); + if (Id == PayloadId) + { + return ValueObject["RawHash"sv].AsHash(); + } + } - ZenCacheValue CacheValue; - if (m_CacheStore.Get(ChunkRequest.Key.Bucket, ChunkRequest.Key.Hash, CacheValue)) + for (CbFieldView AttachmentView : Record["Attachments"sv]) { - CurrentRecordBuffer = CacheValue.Value; + CbObjectView AttachmentObject = AttachmentView.AsObjectView(); + const Oid Id = AttachmentObject["Id"].AsObjectId(); + + if (Id == PayloadId) + { + return AttachmentObject["RawHash"sv].AsHash(); + } } - } - if (CurrentRecordBuffer) + return IoHash::Zero; + }; + + CacheKey CurrentKey = CacheKey::Empty; + IoBuffer CurrentRecordBuffer; + + std::stable_sort(ChunkRequests.begin(), ChunkRequests.end()); + + for (CacheChunkRequest& ChunkRequest : ChunkRequests) { - ChunkRequest.ChunkId = GetChunkIdFromPayloadId(CbObjectView(CurrentRecordBuffer.GetData()), ChunkRequest.PayloadId); - } - } + if (ChunkRequest.Key != CurrentKey) + { + CurrentKey = ChunkRequest.Key; - if (ChunkRequests.empty()) - { - return Request.WriteResponse(HttpResponseCode::BadRequest); - } + ZenCacheValue CacheValue; + if (m_CacheStore.Get(ChunkRequest.Key.Bucket, ChunkRequest.Key.Hash, CacheValue)) + { + CurrentRecordBuffer = CacheValue.Value; + } + } - std::vector Chunks; - Chunks.resize(ChunkRequests.size()); + if (CurrentRecordBuffer) + { + ChunkRequest.ChunkId = GetChunkIdFromPayloadId(CbObjectView(CurrentRecordBuffer.GetData()), ChunkRequest.PayloadId); + } + } + } for (size_t RequestIndex = 0; const CacheChunkRequest& ChunkRequest : ChunkRequests) { @@ -1085,7 +1068,8 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& } else { - Missing.push_back(RequestIndex); + ZEN_DEBUG("MISS - '{}/{}/{}'", ChunkRequest.Key.Bucket, ChunkRequest.Key.Hash, ChunkRequest.ChunkId); + m_CacheStats.MissCount++; } } else @@ -1098,18 +1082,16 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& if (!UpstreamRequests.empty() && m_UpstreamCache) { - const auto OnCachePayloadGetComplete = [this, &ChunkRequests, &Chunks, &Missing](CachePayloadGetCompleteParams&& Params) { - if (Params.Payload) + const auto OnCachePayloadGetComplete = [this, &ChunkRequests, &Chunks](CachePayloadGetCompleteParams&& Params) { + if (CompressedBuffer Compressed = CompressedBuffer::FromCompressed(SharedBuffer(Params.Payload))) { - CompressedBuffer Compressed = CompressedBuffer::FromCompressed(SharedBuffer(Params.Payload)); - auto InsertResult = m_CidStore.AddChunk(Compressed); + auto InsertResult = m_CidStore.AddChunk(Compressed); - ZEN_DEBUG("HIT - '{}/{}/{}' {} '{}' ({})", + ZEN_DEBUG("HIT - '{}/{}/{}' {} ({})", Params.Request.Key.Bucket, Params.Request.Key.Hash, Params.Request.ChunkId, NiceBytes(Params.Payload.GetSize()), - ToString(Params.Payload.GetContentType()), "UPSTREAM"); Chunks[Params.RequestIndex] = std::move(Params.Payload); @@ -1119,43 +1101,37 @@ HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& } else { - Missing.push_back(Params.RequestIndex); + ZEN_DEBUG("MISS - '{}/{}/{}'", Params.Request.Key.Bucket, Params.Request.Key.Hash, Params.Request.ChunkId); + m_CacheStats.MissCount++; } }; m_UpstreamCache->GetCachePayloads(ChunkRequests, UpstreamRequests, std::move(OnCachePayloadGetComplete)); } - for (size_t RequestIndex : Missing) - { - const CacheChunkRequest& ChunkRequest = ChunkRequests[RequestIndex]; - ZEN_DEBUG("MISS - '{}/{}/{}'", ChunkRequest.Key.Bucket, ChunkRequest.Key.Hash, ChunkRequest.ChunkId); - m_CacheStats.MissCount++; - } - - CbPackage Package; - CbObjectWriter BatchResponse; + CbPackage BatchResponse; + CbObjectWriter ResponseObject; - BatchResponse.BeginArray("Result"sv); + ResponseObject.BeginArray("Result"sv); for (size_t ChunkIndex = 0; ChunkIndex < Chunks.size(); ++ChunkIndex) { if (Chunks[ChunkIndex]) { - BatchResponse << ChunkRequests[ChunkIndex].ChunkId; - Package.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(std::move(Chunks[ChunkIndex]))))); + ResponseObject << ChunkRequests[ChunkIndex].ChunkId; + BatchResponse.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(std::move(Chunks[ChunkIndex]))))); } else { - BatchResponse << IoHash::Zero; + ResponseObject << IoHash::Zero; } } - BatchResponse.EndArray(); + ResponseObject.EndArray(); - Package.SetObject(BatchResponse.Save()); + BatchResponse.SetObject(ResponseObject.Save()); BinaryWriter MemStream; - Package.Save(MemStream); + BatchResponse.Save(MemStream); Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kCbPackage, -- cgit v1.2.3 From 6c6b615e82444fbdfb4a2b8cc2ed173a1cf772b5 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Thu, 11 Nov 2021 17:12:14 +0100 Subject: Changed from batch to RPC. --- zenserver/cache/structuredcache.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 10fbb3709..e78e583aa 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -112,9 +112,9 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request) { std::string_view Key = Request.RelativeUri(); - if (Key == "$batch") + if (Key == "$rpc") { - return HandleBatchRequest(Request); + return HandleRpcRequest(Request); } if (std::all_of(begin(Key), end(Key), [](const char c) { return std::isalnum(c); })) @@ -779,7 +779,7 @@ HttpStructuredCacheService::ValidateKeyUri(HttpServerRequest& Request, CacheRef& } void -HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request) +HttpStructuredCacheService::HandleRpcRequest(zen::HttpServerRequest& Request) { switch (auto Verb = Request.RequestVerb()) { @@ -800,11 +800,11 @@ HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request) const std::string_view Method = BatchRequest["Method"sv].AsString(); if (Method == "GetCacheRecords"sv) { - HandleBatchGetCacheRecords(AsyncRequest, BatchRequest); + HandleRpcGetCacheRecords(AsyncRequest, BatchRequest); } else if (Method == "GetCachePayloads"sv) { - HandleBatchGetCachePayloads(AsyncRequest, BatchRequest); + HandleRpcGetCachePayloads(AsyncRequest, BatchRequest); } else { @@ -820,7 +820,7 @@ HttpStructuredCacheService::HandleBatchRequest(zen::HttpServerRequest& Request) } void -HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& Request, CbObjectView BatchRequest) +HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Request, CbObjectView BatchRequest) { using namespace fmt::literals; @@ -959,7 +959,7 @@ HttpStructuredCacheService::HandleBatchGetCacheRecords(zen::HttpServerRequest& R } void -HttpStructuredCacheService::HandleBatchGetCachePayloads(zen::HttpServerRequest& Request, CbObjectView BatchRequest) +HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Request, CbObjectView BatchRequest) { using namespace fmt::literals; -- cgit v1.2.3 From 3faf0b57c625152a8facfca1c4995bd9edc95707 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Fri, 12 Nov 2021 11:08:53 +0100 Subject: Movec cache utility types to zenutil and fixed unit tests. --- zenserver/cache/structuredcache.cpp | 49 ++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 23 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index e78e583aa..1b6406562 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -11,8 +11,9 @@ #include #include #include +#include -#include "cachekey.h" +//#include "cachekey.h" #include "monitoring/httpstats.h" #include "structuredcache.h" #include "structuredcachestore.h" @@ -796,15 +797,15 @@ HttpStructuredCacheService::HandleRpcRequest(zen::HttpServerRequest& Request) } Request.WriteResponseAsync( - [this, BatchRequest = zen::LoadCompactBinaryObject(Request.ReadPayload())](HttpServerRequest& AsyncRequest) { - const std::string_view Method = BatchRequest["Method"sv].AsString(); + [this, RpcRequest = zen::LoadCompactBinaryObject(Request.ReadPayload())](HttpServerRequest& AsyncRequest) { + const std::string_view Method = RpcRequest["Method"sv].AsString(); if (Method == "GetCacheRecords"sv) { - HandleRpcGetCacheRecords(AsyncRequest, BatchRequest); + HandleRpcGetCacheRecords(AsyncRequest, RpcRequest); } else if (Method == "GetCachePayloads"sv) { - HandleRpcGetCachePayloads(AsyncRequest, BatchRequest); + HandleRpcGetCachePayloads(AsyncRequest, RpcRequest); } else { @@ -820,18 +821,18 @@ HttpStructuredCacheService::HandleRpcRequest(zen::HttpServerRequest& Request) } void -HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Request, CbObjectView BatchRequest) +HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Request, CbObjectView RpcRequest) { using namespace fmt::literals; - CbPackage BatchResponse; + CbPackage RpcResponse; CacheRecordPolicy Policy; - CbObjectView Params = BatchRequest["Params"sv].AsObjectView(); + CbObjectView Params = RpcRequest["Params"sv].AsObjectView(); std::vector CacheKeys; std::vector CacheValues; std::vector UpstreamRequests; - ZEN_ASSERT(BatchRequest["Method"sv].AsString() == "GetCacheRecords"sv); + ZEN_ASSERT(RpcRequest["Method"sv].AsString() == "GetCacheRecords"sv); CacheRecordPolicy::Load(Params["Policy"sv].AsObjectView(), Policy); @@ -860,10 +861,10 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req if (!SkipAttachments) { - CacheRecord.IterateAttachments([this, &BatchResponse](CbFieldView AttachmentHash) { + CacheRecord.IterateAttachments([this, &RpcResponse](CbFieldView AttachmentHash) { if (IoBuffer Chunk = m_CidStore.FindChunkByCid(AttachmentHash.AsHash())) { - BatchResponse.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk)))); + RpcResponse.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(Chunk)))); } }); } @@ -893,7 +894,7 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req if (!UpstreamRequests.empty() && m_UpstreamCache) { const auto OnCacheRecordGetComplete = - [this, &CacheKeys, &CacheValues, &BatchResponse, SkipAttachments](CacheRecordGetCompleteParams&& Params) { + [this, &CacheKeys, &CacheValues, &RpcResponse, SkipAttachments](CacheRecordGetCompleteParams&& Params) { if (Params.Record) { Params.Record.IterateAttachments([&](CbFieldView AttachmentHash) { @@ -905,7 +906,7 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req if (!SkipAttachments) { - BatchResponse.AddAttachment(CbAttachment(Compressed)); + RpcResponse.AddAttachment(CbAttachment(Compressed)); } } } @@ -917,6 +918,7 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req NiceBytes(Params.Record.GetView().GetSize()), ToString(HttpContentType::kCbObject)); + ZEN_ASSERT(Params.KeyIndex < CacheValues.size()); CacheValues[Params.KeyIndex] = IoBufferBuilder::MakeCloneFromMemory(Params.Record.GetView()); m_CacheStats.HitCount++; m_CacheStats.UpstreamHitCount++; @@ -948,10 +950,10 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req } ResponseObject.EndArray(); - BatchResponse.SetObject(ResponseObject.Save()); + RpcResponse.SetObject(ResponseObject.Save()); BinaryWriter MemStream; - BatchResponse.Save(MemStream); + RpcResponse.Save(MemStream); Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kCbPackage, @@ -959,16 +961,16 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req } void -HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Request, CbObjectView BatchRequest) +HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Request, CbObjectView RpcRequest) { using namespace fmt::literals; - ZEN_ASSERT(BatchRequest["Method"sv].AsString() == "GetCachePayloads"sv); + ZEN_ASSERT(RpcRequest["Method"sv].AsString() == "GetCachePayloads"sv); std::vector ChunkRequests; std::vector UpstreamRequests; std::vector Chunks; - CbObjectView Params = BatchRequest["Params"sv].AsObjectView(); + CbObjectView Params = RpcRequest["Params"sv].AsObjectView(); for (CbFieldView RequestView : Params["ChunkRequests"sv]) { @@ -1029,7 +1031,7 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re CurrentKey = ChunkRequest.Key; ZenCacheValue CacheValue; - if (m_CacheStore.Get(ChunkRequest.Key.Bucket, ChunkRequest.Key.Hash, CacheValue)) + if (m_CacheStore.Get(CurrentKey.Bucket, CurrentKey.Hash, CacheValue)) { CurrentRecordBuffer = CacheValue.Value; } @@ -1094,6 +1096,7 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re NiceBytes(Params.Payload.GetSize()), "UPSTREAM"); + ZEN_ASSERT(Params.RequestIndex < Chunks.size()); Chunks[Params.RequestIndex] = std::move(Params.Payload); m_CacheStats.HitCount++; @@ -1109,7 +1112,7 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re m_UpstreamCache->GetCachePayloads(ChunkRequests, UpstreamRequests, std::move(OnCachePayloadGetComplete)); } - CbPackage BatchResponse; + CbPackage RpcResponse; CbObjectWriter ResponseObject; ResponseObject.BeginArray("Result"sv); @@ -1119,7 +1122,7 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re if (Chunks[ChunkIndex]) { ResponseObject << ChunkRequests[ChunkIndex].ChunkId; - BatchResponse.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(std::move(Chunks[ChunkIndex]))))); + RpcResponse.AddAttachment(CbAttachment(CompressedBuffer::FromCompressed(SharedBuffer(std::move(Chunks[ChunkIndex]))))); } else { @@ -1128,10 +1131,10 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re } ResponseObject.EndArray(); - BatchResponse.SetObject(ResponseObject.Save()); + RpcResponse.SetObject(ResponseObject.Save()); BinaryWriter MemStream; - BatchResponse.Save(MemStream); + RpcResponse.Save(MemStream); Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kCbPackage, -- cgit v1.2.3 From 58bec60cd39b697d5cd3ab6c757a92e528a638fc Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Fri, 12 Nov 2021 14:36:34 +0100 Subject: Fixed bug when cloning CbObject. --- zenserver/cache/structuredcache.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 1b6406562..d3da98620 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -919,7 +919,8 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req ToString(HttpContentType::kCbObject)); ZEN_ASSERT(Params.KeyIndex < CacheValues.size()); - CacheValues[Params.KeyIndex] = IoBufferBuilder::MakeCloneFromMemory(Params.Record.GetView()); + + CacheValues[Params.KeyIndex] = CbObject::Clone(Params.Record).GetBuffer().AsIoBuffer(); m_CacheStats.HitCount++; m_CacheStats.UpstreamHitCount++; } -- cgit v1.2.3 From 22dcab1d6abeaf1f39581b1f45619aadf81d14cf Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Fri, 12 Nov 2021 16:42:46 +0100 Subject: Relax constraint on partial cache records. --- zenserver/cache/structuredcache.cpp | 132 ++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 72 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index d3da98620..ec27265a7 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -454,52 +454,39 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request CbObjectView CacheRecord(Body.Data()); std::vector ValidAttachments; - uint32_t AttachmentCount = 0; + int32_t TotalCount = 0; - CacheRecord.IterateAttachments([this, &AttachmentCount, &ValidAttachments](CbFieldView AttachmentHash) { + CacheRecord.IterateAttachments([this, &TotalCount, &ValidAttachments](CbFieldView AttachmentHash) { const IoHash Hash = AttachmentHash.AsHash(); if (m_CidStore.ContainsChunk(Hash)) { ValidAttachments.emplace_back(Hash); } - AttachmentCount++; + TotalCount++; }); - const uint32_t ValidCount = static_cast(ValidAttachments.size()); - const bool ValidCacheRecord = ValidCount == AttachmentCount; + const bool IsPartialCacheRecord = TotalCount != static_cast(ValidAttachments.size()); - if (ValidCacheRecord) - { - ZEN_DEBUG("PUT - '{}/{}' {} '{}', {} attachments", - Ref.BucketSegment, - Ref.HashKey, - NiceBytes(Body.Size()), - ToString(ContentType), - ValidCount); - - m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, {.Value = Body}); + ZEN_DEBUG("PUT - '{}/{}' {} '{}', {} attachments {}", + Ref.BucketSegment, + Ref.HashKey, + NiceBytes(Body.Size()), + ToString(ContentType), + ValidAttachments.size(), + IsPartialCacheRecord ? "(PARTIAL)"sv : ""sv); - if (StoreUpstream) - { - ZEN_ASSERT(m_UpstreamCache); - auto Result = m_UpstreamCache->EnqueueUpstream({.Type = ZenContentType::kCbObject, - .CacheKey = {Ref.BucketSegment, Ref.HashKey}, - .PayloadIds = std::move(ValidAttachments)}); - } + Body.SetContentType(ZenContentType::kCbObject); + m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, {.Value = Body}); - Request.WriteResponse(HttpResponseCode::Created); - } - else + if (StoreUpstream && !IsPartialCacheRecord) { - ZEN_WARN("PUT - '{}/{}' '{}' FAILED, found {}/{} attachments", - Ref.BucketSegment, - Ref.HashKey, - ToString(ContentType), - ValidCount, - AttachmentCount); - - Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Missing attachments"sv); + ZEN_ASSERT(m_UpstreamCache); + auto Result = m_UpstreamCache->EnqueueUpstream({.Type = ZenContentType::kCbObject, + .CacheKey = {Ref.BucketSegment, Ref.HashKey}, + .PayloadIds = std::move(ValidAttachments)}); } + + Request.WriteResponse(HttpResponseCode::Created); } else if (ContentType == HttpContentType::kCbPackage) { @@ -511,62 +498,63 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid package"sv); } - CbObject CacheRecord = Package.GetObject(); - - std::span Attachments = Package.GetAttachments(); - std::vector ValidAttachments; - int32_t NewAttachmentCount = 0; + CbObject CacheRecord = Package.GetObject(); + std::vector ValidAttachments; + int32_t TotalCount = 0; + int32_t NewCount = 0; + int32_t InvalidCount = 0; - ValidAttachments.reserve(Attachments.size()); + ValidAttachments.reserve(Package.GetAttachments().size()); - CacheRecord.IterateAttachments([this, &Ref, &Package, &ValidAttachments, &NewAttachmentCount](CbFieldView AttachmentHash) { - if (const CbAttachment* Attachment = Package.FindAttachment(AttachmentHash.AsHash())) - { - if (Attachment->IsCompressedBinary()) + CacheRecord.IterateAttachments( + [this, &Ref, &Package, &ValidAttachments, &TotalCount, &NewCount, &InvalidCount](CbFieldView HashView) { + const IoHash Hash = HashView.AsHash(); + if (const CbAttachment* Attachment = Package.FindAttachment(Hash)) { - CompressedBuffer Chunk = Attachment->AsCompressedBinary(); - CidStore::InsertResult InsertResult = m_CidStore.AddChunk(Chunk); + if (Attachment->IsCompressedBinary()) + { + CompressedBuffer Chunk = Attachment->AsCompressedBinary(); + CidStore::InsertResult InsertResult = m_CidStore.AddChunk(Chunk); - ValidAttachments.emplace_back(InsertResult.DecompressedId); + ValidAttachments.emplace_back(InsertResult.DecompressedId); - if (InsertResult.New) + if (InsertResult.New) + { + NewCount++; + } + } + else { - NewAttachmentCount++; + ZEN_WARN("PUT - '{}/{}' '{}' FAILED, attachment '{}' is not compressed", + Ref.BucketSegment, + Ref.HashKey, + ToString(HttpContentType::kCbPackage), + Hash); + InvalidCount++; } } - else + else if (m_CidStore.ContainsChunk(Hash)) { - ZEN_WARN("PUT - '{}/{}' '{}' FAILED, attachment '{}' is not compressed", - Ref.BucketSegment, - Ref.HashKey, - ToString(HttpContentType::kCbPackage), - AttachmentHash.AsHash()); + ValidAttachments.emplace_back(Hash); } - } - else - { - ZEN_WARN("PUT - '{}/{}' '{}' FAILED, missing attachment '{}'", - Ref.BucketSegment, - Ref.HashKey, - ToString(HttpContentType::kCbPackage), - AttachmentHash.AsHash()); - } - }); + TotalCount++; + }); - const bool IsPartialCacheRecord = ValidAttachments.size() != Attachments.size(); + if (InvalidCount > 0) + { + return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid attachment(s)"sv); + } - // if (!AttachmentsValid) - //{ - // return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid attachments"sv); - //} + const bool IsPartialCacheRecord = TotalCount != static_cast(ValidAttachments.size()); - ZEN_DEBUG("PUT - '{}/{}' {} '{}', {}/{} new attachments", + ZEN_DEBUG("PUT - '{}/{}' {} '{}', {}/{} new attachments {}", Ref.BucketSegment, Ref.HashKey, NiceBytes(Body.GetSize()), ToString(ContentType), - NewAttachmentCount, - Attachments.size()); + NewCount, + TotalCount, + IsPartialCacheRecord ? "(PARTIAL)"sv : ""sv); IoBuffer CacheRecordValue = CacheRecord.GetBuffer().AsIoBuffer(); CacheRecordValue.SetContentType(ZenContentType::kCbObject); -- cgit v1.2.3 From c5cb8971186f376b8296c26d1412d6f44757ac30 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Sat, 13 Nov 2021 14:33:29 +0100 Subject: Cleanup attachment validation. --- zenserver/cache/structuredcache.cpp | 130 +++++++++++++++++++++++------------- 1 file changed, 82 insertions(+), 48 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index ec27265a7..feb8efb2e 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -48,6 +48,14 @@ ParseCachePolicy(const HttpServerRequest::QueryParams& QueryParams) return QueryPolicy | StorePolicy | SkipPolicy; } +struct AttachmentCount +{ + uint32_t New = 0; + uint32_t Valid = 0; + uint32_t Invalid = 0; + uint32_t Total = 0; +}; + ////////////////////////////////////////////////////////////////////////// HttpStructuredCacheService::HttpStructuredCacheService(ZenCacheStore& InCacheStore, @@ -465,20 +473,20 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request TotalCount++; }); - const bool IsPartialCacheRecord = TotalCount != static_cast(ValidAttachments.size()); - - ZEN_DEBUG("PUT - '{}/{}' {} '{}', {} attachments {}", + ZEN_DEBUG("PUT - '{}/{}' {} '{}' attachments '{}/{}' (Valid/Total)", Ref.BucketSegment, Ref.HashKey, NiceBytes(Body.Size()), ToString(ContentType), - ValidAttachments.size(), - IsPartialCacheRecord ? "(PARTIAL)"sv : ""sv); + TotalCount, + ValidAttachments.size()); Body.SetContentType(ZenContentType::kCbObject); m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, {.Value = Body}); - if (StoreUpstream && !IsPartialCacheRecord) + const bool IsPartialRecord = TotalCount != static_cast(ValidAttachments.size()); + + if (StoreUpstream && !IsPartialRecord) { ZEN_ASSERT(m_UpstreamCache); auto Result = m_UpstreamCache->EnqueueUpstream({.Type = ZenContentType::kCbObject, @@ -499,69 +507,68 @@ HttpStructuredCacheService::HandlePutCacheRecord(zen::HttpServerRequest& Request } CbObject CacheRecord = Package.GetObject(); + AttachmentCount Count; std::vector ValidAttachments; - int32_t TotalCount = 0; - int32_t NewCount = 0; - int32_t InvalidCount = 0; ValidAttachments.reserve(Package.GetAttachments().size()); - CacheRecord.IterateAttachments( - [this, &Ref, &Package, &ValidAttachments, &TotalCount, &NewCount, &InvalidCount](CbFieldView HashView) { - const IoHash Hash = HashView.AsHash(); - if (const CbAttachment* Attachment = Package.FindAttachment(Hash)) + CacheRecord.IterateAttachments([this, &Ref, &Package, &ValidAttachments, &Count](CbFieldView HashView) { + const IoHash Hash = HashView.AsHash(); + if (const CbAttachment* Attachment = Package.FindAttachment(Hash)) + { + if (Attachment->IsCompressedBinary()) { - if (Attachment->IsCompressedBinary()) - { - CompressedBuffer Chunk = Attachment->AsCompressedBinary(); - CidStore::InsertResult InsertResult = m_CidStore.AddChunk(Chunk); + CompressedBuffer Chunk = Attachment->AsCompressedBinary(); + CidStore::InsertResult InsertResult = m_CidStore.AddChunk(Chunk); - ValidAttachments.emplace_back(InsertResult.DecompressedId); + ValidAttachments.emplace_back(InsertResult.DecompressedId); - if (InsertResult.New) - { - NewCount++; - } - } - else + if (InsertResult.New) { - ZEN_WARN("PUT - '{}/{}' '{}' FAILED, attachment '{}' is not compressed", - Ref.BucketSegment, - Ref.HashKey, - ToString(HttpContentType::kCbPackage), - Hash); - InvalidCount++; + Count.New++; } + Count.Valid++; } - else if (m_CidStore.ContainsChunk(Hash)) + else { - ValidAttachments.emplace_back(Hash); + ZEN_WARN("PUT - '{}/{}' '{}' FAILED, attachment '{}' is not compressed", + Ref.BucketSegment, + Ref.HashKey, + ToString(HttpContentType::kCbPackage), + Hash); + Count.Invalid++; } - TotalCount++; - }); + } + else if (m_CidStore.ContainsChunk(Hash)) + { + ValidAttachments.emplace_back(Hash); + Count.Valid++; + } + Count.Total++; + }); - if (InvalidCount > 0) + if (Count.Invalid > 0) { return Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid attachment(s)"sv); } - const bool IsPartialCacheRecord = TotalCount != static_cast(ValidAttachments.size()); - - ZEN_DEBUG("PUT - '{}/{}' {} '{}', {}/{} new attachments {}", + ZEN_DEBUG("PUT - '{}/{}' {} '{}', attachments '{}/{}/{}' (New/Valid/Total)", Ref.BucketSegment, Ref.HashKey, NiceBytes(Body.GetSize()), ToString(ContentType), - NewCount, - TotalCount, - IsPartialCacheRecord ? "(PARTIAL)"sv : ""sv); + Count.New, + Count.Valid, + Count.Total); IoBuffer CacheRecordValue = CacheRecord.GetBuffer().AsIoBuffer(); CacheRecordValue.SetContentType(ZenContentType::kCbObject); m_CacheStore.Put(Ref.BucketSegment, Ref.HashKey, {.Value = CacheRecord.GetBuffer().AsIoBuffer()}); - if (StoreUpstream && !IsPartialCacheRecord) + const bool IsPartialRecord = Count.Valid != Count.Total; + + if (StoreUpstream && !IsPartialRecord) { ZEN_ASSERT(m_UpstreamCache); auto Result = m_UpstreamCache->EnqueueUpstream({.Type = ZenContentType::kCbPackage, @@ -885,30 +892,57 @@ HttpStructuredCacheService::HandleRpcGetCacheRecords(zen::HttpServerRequest& Req [this, &CacheKeys, &CacheValues, &RpcResponse, SkipAttachments](CacheRecordGetCompleteParams&& Params) { if (Params.Record) { - Params.Record.IterateAttachments([&](CbFieldView AttachmentHash) { - if (const CbAttachment* Attachment = Params.Package.FindAttachment(AttachmentHash.AsHash())) + AttachmentCount Count; + Params.Record.IterateAttachments([this, &RpcResponse, SkipAttachments, &Params, &Count](CbFieldView HashView) { + if (const CbAttachment* Attachment = Params.Package.FindAttachment(HashView.AsHash())) { if (CompressedBuffer Compressed = Attachment->AsCompressedBinary()) { - m_CidStore.AddChunk(Compressed); + 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.CacheKey.Bucket, + Params.CacheKey.Hash); + Count.Invalid++; + } } + else if (m_CidStore.ContainsChunk(HashView.AsHash())) + { + Count.Valid++; + } + Count.Total++; }); - ZEN_DEBUG("HIT - '{}/{}' {} '{}' (UPSTREAM)", + ZEN_DEBUG("HIT - '{}/{}' {} '{}' attachments '{}/{}/{}' (New/Valid/Total) (UPSTREAM)", Params.CacheKey.Bucket, Params.CacheKey.Hash, NiceBytes(Params.Record.GetView().GetSize()), - ToString(HttpContentType::kCbObject)); + ToString(HttpContentType::kCbPackage), + Count.New, + Count.Valid, + Count.Total); ZEN_ASSERT(Params.KeyIndex < CacheValues.size()); - CacheValues[Params.KeyIndex] = CbObject::Clone(Params.Record).GetBuffer().AsIoBuffer(); + IoBuffer CacheValue = CbObject::Clone(Params.Record).GetBuffer().AsIoBuffer(); + CacheValue.SetContentType(ZenContentType::kCbObject); + + CacheValues[Params.KeyIndex] = CacheValue; + m_CacheStore.Put(Params.CacheKey.Bucket, Params.CacheKey.Hash, {.Value = CacheValue}); + m_CacheStats.HitCount++; m_CacheStats.UpstreamHitCount++; } -- cgit v1.2.3 From d65be761d6c0b7ef74e854862514de55db6a2722 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Sun, 14 Nov 2021 08:51:29 +0100 Subject: Parse chunk ID from chunk request. --- zenserver/cache/structuredcache.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index feb8efb2e..79d370740 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -1000,7 +1000,7 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re 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 = IoHash::Zero; + 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(); @@ -1016,12 +1016,13 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re Chunks.resize(ChunkRequests.size()); - // Try to find the uncompressed raw hash from the payload ID. + // 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. { const auto GetChunkIdFromPayloadId = [](CbObjectView Record, const Oid& PayloadId) -> IoHash { - if (CbObjectView ValueObject = Record["Value"].AsObjectView()) + if (CbObjectView ValueObject = Record["Value"sv].AsObjectView()) { - const Oid Id = ValueObject["Id"].AsObjectId(); + const Oid Id = ValueObject["Id"sv].AsObjectId(); if (Id == PayloadId) { return ValueObject["RawHash"sv].AsHash(); @@ -1031,7 +1032,7 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re for (CbFieldView AttachmentView : Record["Attachments"sv]) { CbObjectView AttachmentObject = AttachmentView.AsObjectView(); - const Oid Id = AttachmentObject["Id"].AsObjectId(); + const Oid Id = AttachmentObject["Id"sv].AsObjectId(); if (Id == PayloadId) { @@ -1049,6 +1050,11 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re for (CacheChunkRequest& ChunkRequest : ChunkRequests) { + if (ChunkRequest.ChunkId != IoHash::Zero) + { + continue; + } + if (ChunkRequest.Key != CurrentKey) { CurrentKey = ChunkRequest.Key; -- cgit v1.2.3 From bfa621a2d3a3e45879728577b0dc3509bbb26ee3 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Sun, 14 Nov 2021 08:53:48 +0100 Subject: Fixed typo in object key. --- 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 79d370740..41a3e807b 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -1002,7 +1002,7 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re 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 RawOffset = RequestObject["RawOffset"sv].AsUInt64(); const uint64_t RawSize = RequestObject["RawSize"sv].AsUInt64(); const uint32_t ChunkPolicy = RequestObject["Policy"sv].AsUInt32(); -- cgit v1.2.3 From 6732450dfc7d488030cea1a1c6d0b28241534db4 Mon Sep 17 00:00:00 2001 From: Per Larsson Date: Sun, 14 Nov 2021 15:05:58 +0100 Subject: Removed sorting of chunk requests. --- zenserver/cache/structuredcache.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'zenserver/cache/structuredcache.cpp') diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp index 41a3e807b..eb31ce5e6 100644 --- a/zenserver/cache/structuredcache.cpp +++ b/zenserver/cache/structuredcache.cpp @@ -1046,8 +1046,6 @@ HttpStructuredCacheService::HandleRpcGetCachePayloads(zen::HttpServerRequest& Re CacheKey CurrentKey = CacheKey::Empty; IoBuffer CurrentRecordBuffer; - std::stable_sort(ChunkRequests.begin(), ChunkRequests.end()); - for (CacheChunkRequest& ChunkRequest : ChunkRequests) { if (ChunkRequest.ChunkId != IoHash::Zero) -- cgit v1.2.3