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