diff options
| author | Stefan Boberg <[email protected]> | 2021-10-21 14:17:18 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-10-21 14:17:18 +0200 |
| commit | efd06036c133654a1799f398345fd1bb3cc632b6 (patch) | |
| tree | dc81e110be0aa8cb025662860843f7f4997f790a /zenserver/zenserver.cpp | |
| parent | Merge branch 'main' into gc (diff) | |
| parent | zenserver: Tweaked state initialization so we know when we're running for the... (diff) | |
| download | zen-efd06036c133654a1799f398345fd1bb3cc632b6.tar.xz zen-efd06036c133654a1799f398345fd1bb3cc632b6.zip | |
Merged from main
Diffstat (limited to 'zenserver/zenserver.cpp')
| -rw-r--r-- | zenserver/zenserver.cpp | 184 |
1 files changed, 110 insertions, 74 deletions
diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp index d3a0afaed..c96fec986 100644 --- a/zenserver/zenserver.cpp +++ b/zenserver/zenserver.cpp @@ -116,6 +116,7 @@ ZEN_THIRD_PARTY_INCLUDES_END namespace zen { using namespace std::literals; +using namespace fmt::literals; class ZenServer : public IHttpStatusProvider { @@ -160,77 +161,7 @@ public: throw std::runtime_error("Failed to create mutex '{}' - is another instance already running?"_format(MutexName).c_str()); } - // Check root manifest to deal with schema versioning - - bool WipeState = false; - std::string WipeReason = "Unspecified"; - - std::filesystem::path ManifestPath = m_DataRoot / "root_manifest"; - FileContents ManifestData = zen::ReadFile(ManifestPath); - - if (ManifestData.ErrorCode) - { - WipeState = true; - WipeReason = "No manifest present at '{}'"_format(ManifestPath); - } - else - { - IoBuffer Manifest = ManifestData.Flatten(); - - if (CbValidateError ValidationResult = ValidateCompactBinary(Manifest, CbValidateMode::All); - ValidationResult != CbValidateError::None) - { - ZEN_ERROR("Manifest validation failed: {}, state will be wiped", ValidationResult); - - WipeState = true; - WipeReason = "Validation of manifest at '{}' failed: {}"_format(ManifestPath, ValidationResult); - } - else - { - m_RootManifest = LoadCompactBinaryObject(Manifest); - - const int32_t ManifestVersion = m_RootManifest["schema_version"].AsInt32(0); - - if (ManifestVersion != ZEN_SCHEMA_VERSION) - { - WipeState = true; - WipeReason = "Manifest schema version: {}, differs from required: {}"_format(ManifestVersion, ZEN_SCHEMA_VERSION); - } - } - } - - // Handle any state wipe - - if (WipeState) - { - ZEN_WARN("Wiping state at '{}' - reason: '{}'", m_DataRoot, WipeReason); - - std::error_code Ec; - for (const std::filesystem::directory_entry& DirEntry : std::filesystem::directory_iterator{m_DataRoot, Ec}) - { - if (DirEntry.is_directory()) - { - ZEN_INFO("Deleting '{}'", DirEntry.path()); - - std::filesystem::remove_all(DirEntry.path(), Ec); - - if (Ec) - { - ZEN_WARN("Delete of '{}' returned error: '{}'", DirEntry.path(), Ec.message()); - } - } - } - - ZEN_INFO("Wiped all directories in data root"); - - // Write new manifest - - CbObjectWriter Cbo; - Cbo << "schema_version" << ZEN_SCHEMA_VERSION; - m_RootManifest = Cbo.Save(); - - WriteFile(ManifestPath, m_RootManifest.GetBuffer().AsIoBuffer()); - } + InitializeState(ServiceConfig); // Ok so now we're configured, let's kick things off @@ -254,8 +185,8 @@ public: ZEN_INFO("instantiating project service"); - m_ProjectStore = new zen::ProjectStore(*m_CasStore, m_DataRoot / "projects"); - m_HttpProjectService.reset(new zen::HttpProjectService{*m_CasStore, m_ProjectStore}); + m_ProjectStore = new zen::ProjectStore(*m_CidStore, m_DataRoot / "projects"); + m_HttpProjectService.reset(new zen::HttpProjectService{*m_CidStore, m_ProjectStore}); #if ZEN_USE_NAMED_PIPES m_LocalProjectService = zen::LocalProjectService::New(*m_CasStore, m_ProjectStore); @@ -329,6 +260,7 @@ public: } } + void InitializeState(ZenServiceConfig& ServiceConfig); void InitializeStructuredCache(ZenServiceConfig& ServiceConfig); #if ZEN_ENABLE_MESH @@ -341,7 +273,9 @@ public: void Run() { - Scrub(); + // This is disabled for now, awaiting better scheduling + // + // Scrub(); if (m_ProcessMonitor.IsActive()) { @@ -567,6 +501,101 @@ private: }; void +ZenServer::InitializeState(ZenServiceConfig& ServiceConfig) +{ + // Check root manifest to deal with schema versioning + + bool WipeState = false; + std::string WipeReason = "Unspecified"; + + bool UpdateManifest = false; + std::filesystem::path ManifestPath = m_DataRoot / "root_manifest"; + FileContents ManifestData = zen::ReadFile(ManifestPath); + + if (ManifestData.ErrorCode) + { + if (ServiceConfig.IsFirstRun) + { + ZEN_INFO("Initializing state at '{}'", m_DataRoot); + + UpdateManifest = true; + } + else + { + WipeState = true; + WipeReason = "No manifest present at '{}'"_format(ManifestPath); + } + } + else + { + IoBuffer Manifest = ManifestData.Flatten(); + + if (CbValidateError ValidationResult = ValidateCompactBinary(Manifest, CbValidateMode::All); + ValidationResult != CbValidateError::None) + { + ZEN_ERROR("Manifest validation failed: {}, state will be wiped", ValidationResult); + + WipeState = true; + WipeReason = "Validation of manifest at '{}' failed: {}"_format(ManifestPath, ValidationResult); + } + else + { + m_RootManifest = LoadCompactBinaryObject(Manifest); + + const int32_t ManifestVersion = m_RootManifest["schema_version"].AsInt32(0); + + if (ManifestVersion != ZEN_SCHEMA_VERSION) + { + WipeState = true; + WipeReason = "Manifest schema version: {}, differs from required: {}"_format(ManifestVersion, ZEN_SCHEMA_VERSION); + } + } + } + + // Handle any state wipe + + if (WipeState) + { + ZEN_WARN("Wiping state at '{}' - reason: '{}'", m_DataRoot, WipeReason); + + std::error_code Ec; + for (const std::filesystem::directory_entry& DirEntry : std::filesystem::directory_iterator{m_DataRoot, Ec}) + { + if (DirEntry.is_directory() && (DirEntry.path().filename() != "logs")) + { + ZEN_INFO("Deleting '{}'", DirEntry.path()); + + std::filesystem::remove_all(DirEntry.path(), Ec); + + if (Ec) + { + ZEN_WARN("Delete of '{}' returned error: '{}'", DirEntry.path(), Ec.message()); + } + } + } + + ZEN_INFO("Wiped all directories in data root"); + + UpdateManifest = true; + } + + if (UpdateManifest) + { + // Write new manifest + + const DateTime Now = DateTime::Now(); + + CbObjectWriter Cbo; + Cbo << "schema_version" << ZEN_SCHEMA_VERSION << "created" << Now << "updated" << Now << "state_id" << Oid::NewOid(); + Cbo << m_RootManifest["id"]; + + m_RootManifest = Cbo.Save(); + + WriteFile(ManifestPath, m_RootManifest.GetBuffer().AsIoBuffer()); + } +} + +void ZenServer::InitializeStructuredCache(ZenServiceConfig& ServiceConfig) { using namespace std::literals; @@ -800,6 +829,13 @@ main(int argc, char* argv[]) ZenServerOptions GlobalOptions; ZenServiceConfig ServiceConfig; ParseGlobalCliOptions(argc, argv, GlobalOptions, ServiceConfig); + + if (!std::filesystem::exists(GlobalOptions.DataDir)) + { + ServiceConfig.IsFirstRun = true; + std::filesystem::create_directories(GlobalOptions.DataDir); + } + InitializeLogging(GlobalOptions); #if ZEN_PLATFORM_WINDOWS |