aboutsummaryrefslogtreecommitdiff
path: root/zenserver/projectstore.h
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-10-17 10:48:32 +0200
committerGitHub <[email protected]>2022-10-17 01:48:32 -0700
commit2493c28b434374c00fa06a928fae8a698a846cb9 (patch)
tree9c366fd7adc96ff2ca4ff43a6ecf9e593ab368f6 /zenserver/projectstore.h
parentAdd "Accept" field in RPC request to gracefully handle requests from older in... (diff)
downloadzen-2493c28b434374c00fa06a928fae8a698a846cb9.tar.xz
zen-2493c28b434374c00fa06a928fae8a698a846cb9.zip
fix concurrency issues in projectstore and enable GC (#181)
* Fix concurreny issues when deleting projects/oplogs * remove rocksdb test code * project store unit tests * safer deletion of oplogs/projects * reference count ProjectStore::Project to handle lifetime during GC * Don't open all project oplogs unless we need them * Don't scrub expired projects * Don't gather references from expired projects * added logging details for GC * release lock as soon as folder is moved * more tests for project store * changelog
Diffstat (limited to 'zenserver/projectstore.h')
-rw-r--r--zenserver/projectstore.h89
1 files changed, 50 insertions, 39 deletions
diff --git a/zenserver/projectstore.h b/zenserver/projectstore.h
index 91c0e1549..00fb613d9 100644
--- a/zenserver/projectstore.h
+++ b/zenserver/projectstore.h
@@ -117,7 +117,13 @@ public:
void Scrub(ScrubContext& Ctx) const;
void GatherReferences(GcContext& GcCtx);
- std::size_t OplogCount() const { return m_LatestOpMap.size(); }
+ std::size_t OplogCount() const
+ {
+ RwLock::SharedLockScope _(m_OplogLock);
+ return m_LatestOpMap.size();
+ }
+
+ std::filesystem::path PrepareForDelete(bool MoveFolder);
private:
struct FileMapEntry
@@ -145,12 +151,16 @@ public:
RefPtr<OplogStorage> m_Storage;
std::string m_OplogId;
- bool AddFileMapping(Oid FileId, IoHash Hash, std::string_view ServerPath, std::string_view ClientPath);
- void AddChunkMapping(Oid ChunkId, IoHash Hash);
- void AddMetaMapping(Oid ChunkId, IoHash Hash);
+ bool AddFileMapping(const RwLock::ExclusiveLockScope& OplogLock,
+ Oid FileId,
+ IoHash Hash,
+ std::string_view ServerPath,
+ std::string_view ClientPath);
+ void AddChunkMapping(const RwLock::ExclusiveLockScope& OplogLock, Oid ChunkId, IoHash Hash);
+ void AddMetaMapping(const RwLock::ExclusiveLockScope& OplogLock, Oid ChunkId, IoHash Hash);
};
- struct Project
+ struct Project : public RefCounted
{
std::string Identifier;
std::filesystem::path RootDir;
@@ -158,16 +168,16 @@ public:
std::string ProjectRootDir;
std::string ProjectFilePath;
- Oplog* NewOplog(std::string_view OplogId);
- Oplog* OpenOplog(std::string_view OplogId);
- void DeleteOplog(std::string_view OplogId);
- void IterateOplogs(std::function<void(const Oplog&)>&& Fn) const;
- void IterateOplogs(std::function<void(Oplog&)>&& Fn);
- void DiscoverOplogs();
- bool IsExpired() const;
+ Oplog* NewOplog(std::string_view OplogId);
+ Oplog* OpenOplog(std::string_view OplogId);
+ void DeleteOplog(std::string_view OplogId);
+ void IterateOplogs(std::function<void(const Oplog&)>&& Fn) const;
+ void IterateOplogs(std::function<void(Oplog&)>&& Fn);
+ std::vector<std::string> ScanForOplogs() const;
+ bool IsExpired() const;
Project(ProjectStore* PrjStore, CidStore& Store, std::filesystem::path BasePath);
- ~Project();
+ virtual ~Project();
void Read();
void Write();
@@ -176,33 +186,34 @@ public:
void Scrub(ScrubContext& Ctx);
spdlog::logger& Log();
void GatherReferences(GcContext& GcCtx);
- void Delete();
+ bool PrepareForDelete(std::filesystem::path& OutDeletePath);
private:
- ProjectStore* m_ProjectStore;
- CidStore& m_CidStore;
- mutable RwLock m_ProjectLock;
- std::map<std::string, Oplog> m_Oplogs;
- std::filesystem::path m_OplogStoragePath;
+ ProjectStore* m_ProjectStore;
+ CidStore& m_CidStore;
+ mutable RwLock m_ProjectLock;
+ std::map<std::string, std::unique_ptr<Oplog>> m_Oplogs;
+ std::vector<std::unique_ptr<Oplog>> m_DeletedOplogs;
+ std::filesystem::path m_OplogStoragePath;
std::filesystem::path BasePathForOplog(std::string_view OplogId);
};
- Oplog* OpenProjectOplog(std::string_view ProjectId, std::string_view OplogId);
-
- Project* OpenProject(std::string_view ProjectId);
- Project* NewProject(std::filesystem::path BasePath,
- std::string_view ProjectId,
- std::string_view RootDir,
- std::string_view EngineRootDir,
- std::string_view ProjectRootDir,
- std::string_view ProjectFilePath);
- void DeleteProject(std::string_view ProjectId, bool OnlyDeleteIfExpired);
- bool Exists(std::string_view ProjectId);
- void Flush();
- void Scrub(ScrubContext& Ctx);
- void DiscoverProjects();
- void IterateProjects(std::function<void(Project& Prj)>&& Fn);
+ // Oplog* OpenProjectOplog(std::string_view ProjectId, std::string_view OplogId);
+
+ Ref<Project> OpenProject(std::string_view ProjectId);
+ Ref<Project> NewProject(std::filesystem::path BasePath,
+ std::string_view ProjectId,
+ std::string_view RootDir,
+ std::string_view EngineRootDir,
+ std::string_view ProjectRootDir,
+ std::string_view ProjectFilePath);
+ bool DeleteProject(std::string_view ProjectId);
+ bool Exists(std::string_view ProjectId);
+ void Flush();
+ void Scrub(ScrubContext& Ctx);
+ void DiscoverProjects();
+ void IterateProjects(std::function<void(Project& Prj)>&& Fn);
spdlog::logger& Log() { return m_Log; }
const std::filesystem::path& BasePath() const { return m_ProjectBasePath; }
@@ -212,11 +223,11 @@ public:
virtual GcStorageSize StorageSize() const override;
private:
- spdlog::logger& m_Log;
- CidStore& m_CidStore;
- std::filesystem::path m_ProjectBasePath;
- RwLock m_ProjectsLock;
- std::map<std::string, Project> m_Projects;
+ spdlog::logger& m_Log;
+ CidStore& m_CidStore;
+ std::filesystem::path m_ProjectBasePath;
+ RwLock m_ProjectsLock;
+ std::map<std::string, Ref<Project>> m_Projects;
std::filesystem::path BasePathForProject(std::string_view ProjectId);
};