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 /zenserver/projectstore.cpp | |
| 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
Diffstat (limited to 'zenserver/projectstore.cpp')
| -rw-r--r-- | zenserver/projectstore.cpp | 103 |
1 files changed, 102 insertions, 1 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(); |