From e4ba07a5404c093c1755779a7034d40262a30ca6 Mon Sep 17 00:00:00 2001 From: orignal Date: Wed, 29 Jan 2025 13:22:15 -0500 Subject: [PATCH] persist local RouterInfo in separate thread using seperate buffer --- libi2pd/RouterContext.cpp | 35 ++++++++++++++++++++++++++++++++++- libi2pd/RouterContext.h | 4 ++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index 53244b6c..ebc3546f 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -78,6 +78,12 @@ namespace i2p m_Service->Stop (); CleanUp (); // GarlicDestination } + if (m_SavingRouterInfo.valid ()) + { + m_SaveBuffer = nullptr; + m_SavingRouterInfo.get (); + } + } std::shared_ptr RouterContext::CopyRouterInfoBuffer () const @@ -254,11 +260,38 @@ namespace i2p void RouterContext::UpdateRouterInfo () { + std::shared_ptr buffer; { std::lock_guard l(m_RouterInfoMutex); m_RouterInfo.CreateBuffer (m_Keys); + buffer = m_RouterInfo.CopyBuffer (); } - m_RouterInfo.SaveToFile (i2p::fs::DataDirPath (ROUTER_INFO)); + { + // update save buffer to latest + std::lock_guard l(m_SaveBufferMutex); + m_SaveBuffer = buffer; + } + bool isSaving = m_SavingRouterInfo.valid (); + if (isSaving && m_SavingRouterInfo.wait_for(std::chrono::seconds(0)) == std::future_status::ready) + { + m_SavingRouterInfo.get (); + isSaving = false; + } + if (!isSaving) // try to save only if not being saved + m_SavingRouterInfo = std::async (std::launch::async, [this]() + { + std::shared_ptr buffer; + while (m_SaveBuffer) + { + { + std::lock_guard l(m_SaveBufferMutex); + buffer = m_SaveBuffer; + m_SaveBuffer = nullptr; + } + if (buffer) + i2p::data::RouterInfo::SaveToFile (i2p::fs::DataDirPath (ROUTER_INFO), buffer); + } + }); m_LastUpdateTime = i2p::util::GetSecondsSinceEpoch (); } diff --git a/libi2pd/RouterContext.h b/libi2pd/RouterContext.h index ae62ebf3..1c724617 100644 --- a/libi2pd/RouterContext.h +++ b/libi2pd/RouterContext.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "Identity.h" @@ -266,6 +267,9 @@ namespace garlic bool m_IsHiddenMode; // not publish mutable std::mutex m_RouterInfoMutex; std::mt19937 m_Rng; + std::future m_SavingRouterInfo; + std::shared_ptr m_SaveBuffer; + std::mutex m_SaveBufferMutex; // TODO: make m_SaveBuffer atomic }; extern RouterContext context;