Loading debian/changelog +9 −0 Original line number Diff line number Diff line authdb (20260411+9) unstable; urgency=medium * Fix cluster node blocking: add per-domain _FetchMutex to serialize concurrent prefetch() calls (prevents thundering herd on retrieve) * prefetch() uses try_lock — if another thread is fetching, wait for its result instead of issuing a parallel cluster retrieve -- Jan Koester <jan.koester@tuxist.de> Sat, 11 Apr 2026 18:00:00 +0200 authdb (20260409+8) unstable; urgency=medium * Use immediate flush (threshold=0) for file_block_store to ensure Loading src/backends/cluster.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -242,8 +242,20 @@ namespace authdb { void ClusterBackend::prefetch() { // Called BEFORE the exclusive lock is acquired. // Performs the blocking network fetch so other threads // are not blocked waiting on cluster I/O. // Serialize fetches per-domain: if another thread is already fetching, // wait for its result instead of hammering the cluster in parallel. std::unique_lock<std::mutex> flk(_FetchMutex, std::try_to_lock); if (!flk.owns_lock()) { // Another thread is already fetching — wait for it to finish. // Its fetchFromCluster() will update _Buffer and _LastPeerFetch. DBG_LOG("[CLUSTER-BE] prefetch() domain=" << _Domain << " — waiting for concurrent fetch\n"); std::lock_guard<std::mutex> wait_lk(_FetchMutex); DBG_LOG("[CLUSTER-BE] prefetch() domain=" << _Domain << " — concurrent fetch done, buf_size=" << _Buffer.size() << "\n"); return; } bool was_dirty = _Dirty.load(); DBG_LOG("[CLUSTER-BE] prefetch() domain=" << _Domain << " buf_size=" << _Buffer.size() << " dirty=" << was_dirty << "\n"); Loading src/backends/cluster.h +2 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <cstdint> #include <atomic> #include <chrono> #include <mutex> #include "../backend.h" #include "../authdb.h" Loading Loading @@ -83,5 +84,6 @@ namespace authdb { std::atomic<bool> _ClusterDataExists{false}; std::chrono::steady_clock::time_point _LastPeerFetch{}; uint64_t _lastRecoveryEpoch{0}; std::mutex _FetchMutex; // serialize per-domain cluster fetches }; }; Loading
debian/changelog +9 −0 Original line number Diff line number Diff line authdb (20260411+9) unstable; urgency=medium * Fix cluster node blocking: add per-domain _FetchMutex to serialize concurrent prefetch() calls (prevents thundering herd on retrieve) * prefetch() uses try_lock — if another thread is fetching, wait for its result instead of issuing a parallel cluster retrieve -- Jan Koester <jan.koester@tuxist.de> Sat, 11 Apr 2026 18:00:00 +0200 authdb (20260409+8) unstable; urgency=medium * Use immediate flush (threshold=0) for file_block_store to ensure Loading
src/backends/cluster.cpp +14 −2 Original line number Diff line number Diff line Loading @@ -242,8 +242,20 @@ namespace authdb { void ClusterBackend::prefetch() { // Called BEFORE the exclusive lock is acquired. // Performs the blocking network fetch so other threads // are not blocked waiting on cluster I/O. // Serialize fetches per-domain: if another thread is already fetching, // wait for its result instead of hammering the cluster in parallel. std::unique_lock<std::mutex> flk(_FetchMutex, std::try_to_lock); if (!flk.owns_lock()) { // Another thread is already fetching — wait for it to finish. // Its fetchFromCluster() will update _Buffer and _LastPeerFetch. DBG_LOG("[CLUSTER-BE] prefetch() domain=" << _Domain << " — waiting for concurrent fetch\n"); std::lock_guard<std::mutex> wait_lk(_FetchMutex); DBG_LOG("[CLUSTER-BE] prefetch() domain=" << _Domain << " — concurrent fetch done, buf_size=" << _Buffer.size() << "\n"); return; } bool was_dirty = _Dirty.load(); DBG_LOG("[CLUSTER-BE] prefetch() domain=" << _Domain << " buf_size=" << _Buffer.size() << " dirty=" << was_dirty << "\n"); Loading
src/backends/cluster.h +2 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <cstdint> #include <atomic> #include <chrono> #include <mutex> #include "../backend.h" #include "../authdb.h" Loading Loading @@ -83,5 +84,6 @@ namespace authdb { std::atomic<bool> _ClusterDataExists{false}; std::chrono::steady_clock::time_point _LastPeerFetch{}; uint64_t _lastRecoveryEpoch{0}; std::mutex _FetchMutex; // serialize per-domain cluster fetches }; };