Loading src/backends/cluster.cpp +17 −9 Changes for src/backends/cluster.cpp: 17 added lines, 9 removed lines. Original line number Diff line number Diff line Loading @@ -63,25 +63,29 @@ namespace authdb { uint64_t dgid = domainGroupId(); // Fetch from local block store (file-backed) // Fetch from local block store (file-backed) — always fast auto &store = g_Cluster->getStore(); std::vector<uint8_t> local_data; try { store.fetch(dgid, 0, local_data); } catch (...) {} // Also try fetching from peer nodes // Only fetch from peers every 5 seconds to avoid blocking // the backend lock with slow network I/O on every request. std::vector<uint8_t> peer_data; auto now = std::chrono::steady_clock::now(); bool do_peer_fetch = (now - _LastPeerFetch) >= std::chrono::seconds(5); if (do_peer_fetch) { auto &client = g_Cluster->getClient(); if (client) { try { auto &cmtx = g_Cluster->getClientMutex(); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(3)); if (lock.owns_lock()) { client->fetch_from_peers(dgid, 0, peer_data); } catch (const netplus::NetException &e) { std::cerr << "ClusterBackend::fetchFromCluster: fetch_from_peers failed: " << e.what() << std::endl; _LastPeerFetch = now; } } catch (const std::exception &e) { std::cerr << "ClusterBackend::fetchFromCluster: fetch_from_peers failed: " << e.what() << std::endl; Loading @@ -89,6 +93,7 @@ namespace authdb { std::cerr << "ClusterBackend::fetchFromCluster: fetch_from_peers failed (unknown)" << std::endl; } } } // Pick the buffer with the highest revision (most recent writes) size_t local_rev = bufferRevision(local_data); Loading Loading @@ -147,9 +152,12 @@ namespace authdb { if (client) { try { auto &cmtx = g_Cluster->getClientMutex(); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(3)); if (lock.owns_lock()) { client->replicate_to_peers(dgid, 0, _Buffer.data(), _Buffer.size()); } else { std::cerr << "ClusterBackend::pushToCluster: skipped replication (lock busy)" << std::endl; } } catch (const netplus::NetException &e) { std::cerr << "Cluster replicate failed: " << e.what() << std::endl; } catch (const std::exception &e) { Loading src/backends/cluster.h +1 −0 Changes for src/backends/cluster.h: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -70,5 +70,6 @@ namespace authdb { std::vector<uint8_t> _Buffer; size_t _Pos; bool _Dirty; std::chrono::steady_clock::time_point _LastPeerFetch{}; }; }; src/cluster.cpp +8 −8 Changes for src/cluster.cpp: 8 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -392,7 +392,7 @@ namespace authdb { // Replicate raw data to all peer nodes under both keys try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); pclient_->replicate_to_peers(sgid, 0, data.data(), data.size()); pclient_->replicate_to_peers(sid_gid, 0, data.data(), data.size()); } catch (const netplus::NetException &e) { Loading Loading @@ -420,7 +420,7 @@ namespace authdb { // Try to fetch from peer nodes if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); if (pclient_->fetch_from_peers(sgid, 0, data) && !data.empty()) { uuid::uuid d_uid, d_did; if (SessionBlock::deserialize(data, sid, d_uid, d_did, members, username, gpo_results)) { Loading Loading @@ -452,7 +452,7 @@ namespace authdb { store_->remove_group(sid_gid); if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); pclient_->remove(sid_gid); } catch (...) {} } Loading @@ -464,7 +464,7 @@ namespace authdb { if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); pclient_->remove(sgid); } catch (...) {} } Loading @@ -480,7 +480,7 @@ namespace authdb { // Check peer nodes if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); if (pclient_->fetch_from_peers(sgid, 0, data) && !data.empty()) return true; } catch (...) {} Loading @@ -499,7 +499,7 @@ namespace authdb { // Check peer nodes if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); if (pclient_->fetch_from_peers(sid_gid, 0, data) && !data.empty()) return true; } catch (...) {} Loading @@ -526,7 +526,7 @@ namespace authdb { // Try to fetch from peer nodes if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); if (pclient_->fetch_from_peers(sid_gid, 0, data) && !data.empty()) { if (SessionBlock::deserialize(data, sid, uid, did, members, username, gpo_results)) { // Cache locally Loading Loading @@ -674,7 +674,7 @@ namespace authdb { // Replicate to all peer nodes try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); pclient_->replicate_to_peers(localId, 0, data.data(), data.size()); } catch (const netplus::NetException &e) { std::cerr << "Cluster replicate failed: " << e.what() << std::endl; Loading Loading
src/backends/cluster.cpp +17 −9 Changes for src/backends/cluster.cpp: 17 added lines, 9 removed lines. Original line number Diff line number Diff line Loading @@ -63,25 +63,29 @@ namespace authdb { uint64_t dgid = domainGroupId(); // Fetch from local block store (file-backed) // Fetch from local block store (file-backed) — always fast auto &store = g_Cluster->getStore(); std::vector<uint8_t> local_data; try { store.fetch(dgid, 0, local_data); } catch (...) {} // Also try fetching from peer nodes // Only fetch from peers every 5 seconds to avoid blocking // the backend lock with slow network I/O on every request. std::vector<uint8_t> peer_data; auto now = std::chrono::steady_clock::now(); bool do_peer_fetch = (now - _LastPeerFetch) >= std::chrono::seconds(5); if (do_peer_fetch) { auto &client = g_Cluster->getClient(); if (client) { try { auto &cmtx = g_Cluster->getClientMutex(); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(3)); if (lock.owns_lock()) { client->fetch_from_peers(dgid, 0, peer_data); } catch (const netplus::NetException &e) { std::cerr << "ClusterBackend::fetchFromCluster: fetch_from_peers failed: " << e.what() << std::endl; _LastPeerFetch = now; } } catch (const std::exception &e) { std::cerr << "ClusterBackend::fetchFromCluster: fetch_from_peers failed: " << e.what() << std::endl; Loading @@ -89,6 +93,7 @@ namespace authdb { std::cerr << "ClusterBackend::fetchFromCluster: fetch_from_peers failed (unknown)" << std::endl; } } } // Pick the buffer with the highest revision (most recent writes) size_t local_rev = bufferRevision(local_data); Loading Loading @@ -147,9 +152,12 @@ namespace authdb { if (client) { try { auto &cmtx = g_Cluster->getClientMutex(); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(3)); if (lock.owns_lock()) { client->replicate_to_peers(dgid, 0, _Buffer.data(), _Buffer.size()); } else { std::cerr << "ClusterBackend::pushToCluster: skipped replication (lock busy)" << std::endl; } } catch (const netplus::NetException &e) { std::cerr << "Cluster replicate failed: " << e.what() << std::endl; } catch (const std::exception &e) { Loading
src/backends/cluster.h +1 −0 Changes for src/backends/cluster.h: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -70,5 +70,6 @@ namespace authdb { std::vector<uint8_t> _Buffer; size_t _Pos; bool _Dirty; std::chrono::steady_clock::time_point _LastPeerFetch{}; }; };
src/cluster.cpp +8 −8 Changes for src/cluster.cpp: 8 added lines, 8 removed lines. Original line number Diff line number Diff line Loading @@ -392,7 +392,7 @@ namespace authdb { // Replicate raw data to all peer nodes under both keys try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); pclient_->replicate_to_peers(sgid, 0, data.data(), data.size()); pclient_->replicate_to_peers(sid_gid, 0, data.data(), data.size()); } catch (const netplus::NetException &e) { Loading Loading @@ -420,7 +420,7 @@ namespace authdb { // Try to fetch from peer nodes if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); if (pclient_->fetch_from_peers(sgid, 0, data) && !data.empty()) { uuid::uuid d_uid, d_did; if (SessionBlock::deserialize(data, sid, d_uid, d_did, members, username, gpo_results)) { Loading Loading @@ -452,7 +452,7 @@ namespace authdb { store_->remove_group(sid_gid); if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); pclient_->remove(sid_gid); } catch (...) {} } Loading @@ -464,7 +464,7 @@ namespace authdb { if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); pclient_->remove(sgid); } catch (...) {} } Loading @@ -480,7 +480,7 @@ namespace authdb { // Check peer nodes if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); if (pclient_->fetch_from_peers(sgid, 0, data) && !data.empty()) return true; } catch (...) {} Loading @@ -499,7 +499,7 @@ namespace authdb { // Check peer nodes if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); if (pclient_->fetch_from_peers(sid_gid, 0, data) && !data.empty()) return true; } catch (...) {} Loading @@ -526,7 +526,7 @@ namespace authdb { // Try to fetch from peer nodes if (pclient_) { try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); if (pclient_->fetch_from_peers(sid_gid, 0, data) && !data.empty()) { if (SessionBlock::deserialize(data, sid, uid, did, members, username, gpo_results)) { // Cache locally Loading Loading @@ -674,7 +674,7 @@ namespace authdb { // Replicate to all peer nodes try { std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(15)); if (!lock.owns_lock()) throw std::runtime_error("cluster client lock timeout"); pclient_->replicate_to_peers(localId, 0, data.data(), data.size()); } catch (const netplus::NetException &e) { std::cerr << "Cluster replicate failed: " << e.what() << std::endl; Loading