diff options
| author | Dan Engelbrecht <[email protected]> | 2022-10-17 10:48:32 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-10-17 01:48:32 -0700 |
| commit | 2493c28b434374c00fa06a928fae8a698a846cb9 (patch) | |
| tree | 9c366fd7adc96ff2ca4ff43a6ecf9e593ab368f6 /zenserver/projectstore.h | |
| parent | Add "Accept" field in RPC request to gracefully handle requests from older in... (diff) | |
| download | zen-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.h | 89 |
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); }; |