diff options
| author | Stefan Boberg <[email protected]> | 2026-04-21 10:07:03 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-04-21 10:07:03 +0200 |
| commit | 2ade130ec3c163cadc4a296e7d7800eb86e72056 (patch) | |
| tree | 7f3332551322ee2e206ee5ae9f9d30b80d45b204 /src | |
| parent | Zen CLI common server interface (#920) (diff) | |
| download | archived-zen-2ade130ec3c163cadc4a296e7d7800eb86e72056.tar.xz archived-zen-2ade130ec3c163cadc4a296e7d7800eb86e72056.zip | |
structured cache: fix some minor issues (#995)
- Fix double WriteResponse in PUT record failure path; the detail-body branch now short-circuits instead of falling through to a second WriteResponse call
- Return 405 Method Not Allowed for unsupported verbs in the root, namespace, bucket, record, and chunk handlers (previously fell through to no response)
- Clamp exec$/replay-recording thread_count so a bogus query value cannot spawn an unbounded worker pool
## Performance / cleanup
- NamespaceMap now uses TransparentStringHash + std::equal_to<>, so Get/Put/Find/Drop can probe the map with a std::string_view directly instead of constructing a temporary std::string on every request
- Replace insert_or_assign with try_emplace under the exclusive lock in GetNamespace; the find() re-check already guarantees the key is absent, so try_emplace matches intent better
## Reverted
- The earlier change to erase the pinned entry from m_DroppedNamespaces after DropNamespace's post-drop work was reverted: other threads may still hold pointers into a dropped namespace, so tearing it down eagerly is unsafe. Dropped namespaces remain pinned for the lifetime of the process as before.
Diffstat (limited to 'src')
| -rw-r--r-- | src/zenserver/storage/cache/httpstructuredcache.cpp | 27 | ||||
| -rw-r--r-- | src/zenstore/cache/structuredcachestore.cpp | 22 | ||||
| -rw-r--r-- | src/zenstore/include/zenstore/cache/structuredcachestore.h | 3 |
3 files changed, 29 insertions, 23 deletions
diff --git a/src/zenserver/storage/cache/httpstructuredcache.cpp b/src/zenserver/storage/cache/httpstructuredcache.cpp index 8ad48225b..4d3673e70 100644 --- a/src/zenserver/storage/cache/httpstructuredcache.cpp +++ b/src/zenserver/storage/cache/httpstructuredcache.cpp @@ -437,19 +437,22 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request) std::string RecordPath = UrlDecode(Params.GetValue("path")); - uint32_t ThreadCount = GetHardwareConcurrency(); + const uint32_t HardwareConcurrency = GetHardwareConcurrency(); + const uint32_t MaxThreadCount = std::max<uint32_t>(HardwareConcurrency, 16u); + uint32_t ThreadCount = HardwareConcurrency; if (auto Param = Params.GetValue("thread_count"); Param.empty() == false) { if (auto Value = ParseInt<uint64_t>(Param)) { - ThreadCount = gsl::narrow<uint32_t>(Value.value()); + ThreadCount = gsl::narrow_cast<uint32_t>(std::min<uint64_t>(Value.value(), MaxThreadCount)); } } + ThreadCount = std::clamp<uint32_t>(ThreadCount, 1u, MaxThreadCount); ZEN_INFO("initiating cache RPC replay using {} threads, from '{}'", ThreadCount, RecordPath); std::unique_ptr<cache::IRpcRequestReplayer> Replayer(cache::MakeDiskRequestReplayer(RecordPath, false)); - ReplayRequestRecorder(RequestContext, *Replayer, ThreadCount < 1 ? 1 : ThreadCount); + ReplayRequestRecorder(RequestContext, *Replayer, ThreadCount); ZEN_INFO("cache RPC replay COMPLETED"); @@ -557,7 +560,7 @@ HttpStructuredCacheService::HandleCacheRequest(HttpServerRequest& Request) break; default: m_CacheStats.BadRequestCount++; - break; + return Request.WriteResponse(HttpResponseCode::MethodNotAllowed); } } @@ -707,7 +710,8 @@ HttpStructuredCacheService::HandleCacheNamespaceRequest(HttpServerRequest& Reque break; default: - break; + m_CacheStats.BadRequestCount++; + return Request.WriteResponse(HttpResponseCode::MethodNotAllowed); } } @@ -797,7 +801,8 @@ HttpStructuredCacheService::HandleCacheBucketRequest(HttpServerRequest& Request, break; default: - break; + m_CacheStats.BadRequestCount++; + return Request.WriteResponse(HttpResponseCode::MethodNotAllowed); } } @@ -816,7 +821,8 @@ HttpStructuredCacheService::HandleCacheRecordRequest(HttpServerRequest& Request, break; default: - break; + m_CacheStats.BadRequestCount++; + return Request.WriteResponse(HttpResponseCode::MethodNotAllowed); } } @@ -1216,8 +1222,6 @@ HttpStructuredCacheService::HandlePutCacheRecord(HttpServerRequest& Request, con } auto WriteFailureResponse = [&Request](const ZenCacheStore::PutResult& PutResult) { - ZEN_UNUSED(PutResult); - HttpResponseCode ResponseCode = HttpResponseCode::InternalServerError; switch (PutResult.Status) { @@ -1231,7 +1235,7 @@ HttpStructuredCacheService::HandlePutCacheRecord(HttpServerRequest& Request, con if (PutResult.Details) { - Request.WriteResponse(ResponseCode, PutResult.Details); + return Request.WriteResponse(ResponseCode, PutResult.Details); } return Request.WriteResponse(ResponseCode); }; @@ -1507,7 +1511,8 @@ HttpStructuredCacheService::HandleCacheChunkRequest(HttpServerRequest& Request, HandlePutCacheChunk(Request, Ref, PolicyFromUrl); break; default: - break; + m_CacheStats.BadRequestCount++; + return Request.WriteResponse(HttpResponseCode::MethodNotAllowed); } } diff --git a/src/zenstore/cache/structuredcachestore.cpp b/src/zenstore/cache/structuredcachestore.cpp index 97b793083..990238e1e 100644 --- a/src/zenstore/cache/structuredcachestore.cpp +++ b/src/zenstore/cache/structuredcachestore.cpp @@ -817,7 +817,7 @@ ZenCacheStore::DropNamespace(std::string_view InNamespace) std::function<void()> PostDropOp; { RwLock::ExclusiveLockScope _(m_NamespacesLock); - if (auto It = m_Namespaces.find(std::string(InNamespace)); It != m_Namespaces.end()) + if (auto It = m_Namespaces.find(InNamespace); It != m_Namespaces.end()) { ZenCacheNamespace& Namespace = *It->second; m_DroppedNamespaces.push_back(std::move(It->second)); @@ -888,13 +888,13 @@ ZenCacheNamespace* ZenCacheStore::GetNamespace(std::string_view Namespace) { RwLock::SharedLockScope _(m_NamespacesLock); - if (auto It = m_Namespaces.find(std::string(Namespace)); It != m_Namespaces.end()) + if (auto It = m_Namespaces.find(Namespace); It != m_Namespaces.end()) { return It->second.get(); } if (Namespace == DefaultNamespace) { - if (auto It = m_Namespaces.find(std::string(UE4DDCNamespaceName)); It != m_Namespaces.end()) + if (auto It = m_Namespaces.find(UE4DDCNamespaceName); It != m_Namespaces.end()) { return It->second.get(); } @@ -907,17 +907,17 @@ ZenCacheStore::GetNamespace(std::string_view Namespace) } RwLock::ExclusiveLockScope __(m_NamespacesLock); - if (auto It = m_Namespaces.find(std::string(Namespace)); It != m_Namespaces.end()) + if (auto It = m_Namespaces.find(Namespace); It != m_Namespaces.end()) { return It->second.get(); } auto NewNamespace = - m_Namespaces.insert_or_assign(std::string(Namespace), - std::make_unique<ZenCacheNamespace>(m_Gc, - m_JobQueue, - m_BasePath / fmt::format("{}{}", NamespaceDiskPrefix, Namespace), - m_Configuration.NamespaceConfig)); + m_Namespaces.try_emplace(std::string(Namespace), + std::make_unique<ZenCacheNamespace>(m_Gc, + m_JobQueue, + m_BasePath / fmt::format("{}{}", NamespaceDiskPrefix, Namespace), + m_Configuration.NamespaceConfig)); if (m_CapturedNamespaces) { @@ -931,13 +931,13 @@ const ZenCacheNamespace* ZenCacheStore::FindNamespace(std::string_view Namespace) const { RwLock::SharedLockScope _(m_NamespacesLock); - if (auto It = m_Namespaces.find(std::string(Namespace)); It != m_Namespaces.end()) + if (auto It = m_Namespaces.find(Namespace); It != m_Namespaces.end()) { return It->second.get(); } if (Namespace == DefaultNamespace) { - if (auto It = m_Namespaces.find(std::string(UE4DDCNamespaceName)); It != m_Namespaces.end()) + if (auto It = m_Namespaces.find(UE4DDCNamespaceName); It != m_Namespaces.end()) { return It->second.get(); } diff --git a/src/zenstore/include/zenstore/cache/structuredcachestore.h b/src/zenstore/include/zenstore/cache/structuredcachestore.h index 3722a0d31..9e0561364 100644 --- a/src/zenstore/include/zenstore/cache/structuredcachestore.h +++ b/src/zenstore/include/zenstore/cache/structuredcachestore.h @@ -3,6 +3,7 @@ #pragma once #include <zencore/compactbinary.h> +#include <zencore/hashutils.h> #include <zencore/iohash.h> #include <zenstore/cache/cache.h> #include <zenstore/cache/cachedisklayer.h> @@ -307,7 +308,7 @@ private: ZenCacheNamespace* GetNamespace(std::string_view Namespace); void IterateNamespaces(const std::function<void(std::string_view Namespace, ZenCacheNamespace& Store)>& Callback) const; - typedef std::unordered_map<std::string, std::unique_ptr<ZenCacheNamespace>> NamespaceMap; + typedef std::unordered_map<std::string, std::unique_ptr<ZenCacheNamespace>, TransparentStringHash, std::equal_to<>> NamespaceMap; CacheStoreStats m_LastReportedMetrics; const DiskWriteBlocker* m_DiskWriteBlocker = nullptr; |