diff options
| author | Stefan Boberg <[email protected]> | 2021-08-12 10:06:36 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-08-12 10:06:36 +0200 |
| commit | cfa13ce97d84fab0ce21d8d3f81c20043afd002d (patch) | |
| tree | be3e21f2d05fa193da65b5ee03ff2d88b8a0be9d | |
| parent | Implemented flush operations for cache services (diff) | |
| download | zen-cfa13ce97d84fab0ce21d8d3f81c20043afd002d.tar.xz zen-cfa13ce97d84fab0ce21d8d3f81c20043afd002d.zip | |
Added {project}/oplog/{log}/{hash} endpoint (implemented by Matt Peters)
Added project store flush implementation
| -rw-r--r-- | zenserver/projectstore.cpp | 103 | ||||
| -rw-r--r-- | zenserver/projectstore.h | 6 |
2 files changed, 106 insertions, 3 deletions
diff --git a/zenserver/projectstore.cpp b/zenserver/projectstore.cpp index e745972d3..750ecdb6a 100644 --- a/zenserver/projectstore.cpp +++ b/zenserver/projectstore.cpp @@ -289,7 +289,16 @@ ProjectStore::Oplog::Oplog(std::string_view Id, Project* Outer, CasStore& Store, zen::CleanDirectory(m_TempPath); } -ProjectStore::Oplog::~Oplog() = default; +ProjectStore::Oplog::~Oplog() +{ + Flush(); +} + +void +ProjectStore::Oplog::Flush() +{ + m_Storage->Flush(); +} bool ProjectStore::Oplog::ExistsAt(std::filesystem::path BasePath) @@ -721,6 +730,12 @@ ProjectStore::Project::IterateOplogs(std::function<void(const Oplog&)>&& Fn) con } } +void +ProjectStore::Project::Flush() +{ + // TODO +} + ////////////////////////////////////////////////////////////////////////// ProjectStore::ProjectStore(CasStore& Store, std::filesystem::path BasePath) @@ -743,6 +758,19 @@ ProjectStore::BasePathForProject(std::string_view ProjectId) return m_ProjectBasePath / ProjectId; } +void +ProjectStore::Flush() +{ + // TODO + + RwLock::SharedLockScope _(m_ProjectsLock); + + for (auto& Kv : m_Projects) + { + Kv.second.Flush(); + } +} + ProjectStore::Project* ProjectStore::OpenProject(std::string_view ProjectId) { @@ -843,6 +871,7 @@ HttpProjectService::HttpProjectService(CasStore& Store, ProjectStore* Projects) m_Router.AddPattern("log", "([[:alnum:]_.]+)"); m_Router.AddPattern("op", "([[:digit:]]+?)"); m_Router.AddPattern("chunk", "([[:xdigit:]]{24})"); + m_Router.AddPattern("hash", "([[:xdigit:]]{40})"); m_Router.RegisterRoute( "{project}/oplog/{log}/batch", @@ -1143,6 +1172,78 @@ HttpProjectService::HttpProjectService(CasStore& Store, ProjectStore* Projects) HttpVerb::kGet | HttpVerb::kHead); m_Router.RegisterRoute( + "{project}/oplog/{log}/{hash}", + [this](HttpRouterRequest& Req) { + HttpServerRequest& HttpReq = Req.ServerRequest(); + + const auto& ProjectId = Req.GetCapture(1); + const auto& OplogId = Req.GetCapture(2); + const auto& HashString = Req.GetCapture(3); + + bool IsOffset = false; + uint64_t Offset = 0; + uint64_t Size = ~(0ull); + + auto QueryParms = Req.ServerRequest().GetQueryParams(); + + if (auto OffsetParm = QueryParms.GetValue("offset"); OffsetParm.empty() == false) + { + if (auto OffsetVal = ParseInt<uint64_t>(OffsetParm)) + { + Offset = OffsetVal.value(); + IsOffset = true; + } + else + { + return HttpReq.WriteResponse(HttpResponse::BadRequest); + } + } + + if (auto SizeParm = QueryParms.GetValue("size"); SizeParm.empty() == false) + { + if (auto SizeVal = ParseInt<uint64_t>(SizeParm)) + { + Size = SizeVal.value(); + IsOffset = true; + } + else + { + return HttpReq.WriteResponse(HttpResponse::BadRequest); + } + } + + m_Log.debug("oplog hash - {} / {} / {}", ProjectId, OplogId, HashString); + + IoHash Hash = IoHash::FromHexString(HashString); + IoBuffer Value = m_CasStore.FindChunk(Hash); + if (!Value) + { + return HttpReq.WriteResponse(HttpResponse::NotFound); + } + + if (IsOffset) + { + if (Offset > Value.Size()) + { + Offset = Value.Size(); + } + + if ((Offset + Size) > Value.Size()) + { + Size = Value.Size() - Offset; + } + + // Send only a subset of data + IoBuffer InnerValue(Value, Offset, Size); + + return HttpReq.WriteResponse(HttpResponse::OK, HttpContentType::kBinary, InnerValue); + } + + return HttpReq.WriteResponse(HttpResponse::OK, HttpContentType::kBinary, Value); + }, + HttpVerb::kGet); + + m_Router.RegisterRoute( "{project}/oplog/{log}/prep", [this](HttpRouterRequest& Req) { HttpServerRequest& HttpReq = Req.ServerRequest(); diff --git a/zenserver/projectstore.h b/zenserver/projectstore.h index 621d7be05..33bacfdaa 100644 --- a/zenserver/projectstore.h +++ b/zenserver/projectstore.h @@ -100,6 +100,7 @@ public: const std::filesystem::path& TempPath() const { return m_TempPath; } spdlog::logger& Log() { return m_OuterProject->Log(); } + void Flush(); std::size_t OplogCount() const { return m_LatestOpMap.size(); } @@ -152,8 +153,8 @@ public: void Read(); void Write(); [[nodiscard]] static bool Exists(std::filesystem::path BasePath); - - spdlog::logger& Log(); + void Flush(); + spdlog::logger& Log(); private: ProjectStore* m_ProjectStore; @@ -175,6 +176,7 @@ public: std::string_view ProjectRootDir); void DeleteProject(std::string_view ProjectId); bool Exists(std::string_view ProjectId); + void Flush(); spdlog::logger& Log() { return m_Log; } const std::filesystem::path& BasePath() const { return m_ProjectBasePath; } |