aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-04-21 10:07:03 +0200
committerGitHub Enterprise <[email protected]>2026-04-21 10:07:03 +0200
commit2ade130ec3c163cadc4a296e7d7800eb86e72056 (patch)
tree7f3332551322ee2e206ee5ae9f9d30b80d45b204 /src
parentZen CLI common server interface (#920) (diff)
downloadarchived-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.cpp27
-rw-r--r--src/zenstore/cache/structuredcachestore.cpp22
-rw-r--r--src/zenstore/include/zenstore/cache/structuredcachestore.h3
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;