Loading src/backends/cluster.cpp +19 −7 Original line number Diff line number Diff line Loading @@ -235,13 +235,25 @@ namespace authdb { if (_Dirty) { newRevesion(); uint64_t dgid = domainGroupId(); if (pushToClusterAsync(dgid, _Buffer)) { DBG_LOG("[CLUSTER-BE] unlock() push OK\n"); _Dirty = false; } else { DBG_LOG("[CLUSTER-BE] unlock() push FAILED, dirty stays true\n"); // Push in a detached background thread so unlock() never blocks // the HTTP response on cluster timeouts. auto buf_copy = std::make_shared<std::vector<uint8_t>>(_Buffer); std::thread([dgid, buf_copy]() { if (!g_Cluster || !g_Cluster->isRunning()) return; auto &client = g_Cluster->getClient(); if (!client) return; try { auto &cmtx = g_Cluster->getClientMutex(); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(5)); if (lock.owns_lock()) { client->store(dgid, buf_copy->data(), buf_copy->size()); } } catch (const std::exception &e) { std::cerr << "Cluster replicate (bg): " << e.what() << std::endl; } // If push failed, _Dirty stays true so next unlock() retries }).detach(); // Optimistically clear dirty — data is captured in bg thread _Dirty = false; } } Loading src/cluster.cpp +15 −14 Original line number Diff line number Diff line Loading @@ -425,9 +425,11 @@ namespace authdb { } void Cluster::pushSession(const SessionData &sess) { auto data = SessionBlock::serialize(sess); if (!pclient_) return; uuid::uuid sid, uid, did; auto data = std::make_shared<std::vector<uint8_t>>(SessionBlock::serialize(sess)); uuid::uuid uid, did, sid; sess.getSid(sid); sess.getUid(uid); sess.getDid(did); Loading @@ -435,18 +437,17 @@ namespace authdb { uint64_t sgid = sessionGroupId(uid, did); uint64_t sid_gid = sidGroupId(sid); if (!pclient_) return; // Distribute erasure-coded shards across peer nodes // Push in background thread so login response isn't blocked by timeouts std::thread([this, data, sgid, sid_gid]() { 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"); pclient_->store(sgid, data.data(), data.size()); pclient_->store(sid_gid, data.data(), data.size()); } catch (const netplus::NetException &e) { std::cerr << "Cluster push session failed: " << e.what() << std::endl; std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) return; pclient_->store(sgid, data->data(), data->size()); pclient_->store(sid_gid, data->data(), data->size()); } catch (const std::exception &e) { std::cerr << "Cluster push session failed: " << e.what() << std::endl; std::cerr << "Cluster push session (bg): " << e.what() << std::endl; } }).detach(); } bool Cluster::fetchSession(const uuid::uuid &uid, const uuid::uuid &did, Loading src/session.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -532,11 +532,9 @@ const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid session cur->_members = c_members; cur->_username = c_username; cur->setGPOResults(c_gpo); } else { // Session removed on another node — purge local copy removeLocal(sessionid); return nullptr; } // If fetch fails (peers unreachable), just use the local session as-is. // Do NOT remove — the session is valid locally even if cluster is down. } return cur; } Loading Loading
src/backends/cluster.cpp +19 −7 Original line number Diff line number Diff line Loading @@ -235,13 +235,25 @@ namespace authdb { if (_Dirty) { newRevesion(); uint64_t dgid = domainGroupId(); if (pushToClusterAsync(dgid, _Buffer)) { DBG_LOG("[CLUSTER-BE] unlock() push OK\n"); _Dirty = false; } else { DBG_LOG("[CLUSTER-BE] unlock() push FAILED, dirty stays true\n"); // Push in a detached background thread so unlock() never blocks // the HTTP response on cluster timeouts. auto buf_copy = std::make_shared<std::vector<uint8_t>>(_Buffer); std::thread([dgid, buf_copy]() { if (!g_Cluster || !g_Cluster->isRunning()) return; auto &client = g_Cluster->getClient(); if (!client) return; try { auto &cmtx = g_Cluster->getClientMutex(); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(5)); if (lock.owns_lock()) { client->store(dgid, buf_copy->data(), buf_copy->size()); } } catch (const std::exception &e) { std::cerr << "Cluster replicate (bg): " << e.what() << std::endl; } // If push failed, _Dirty stays true so next unlock() retries }).detach(); // Optimistically clear dirty — data is captured in bg thread _Dirty = false; } } Loading
src/cluster.cpp +15 −14 Original line number Diff line number Diff line Loading @@ -425,9 +425,11 @@ namespace authdb { } void Cluster::pushSession(const SessionData &sess) { auto data = SessionBlock::serialize(sess); if (!pclient_) return; uuid::uuid sid, uid, did; auto data = std::make_shared<std::vector<uint8_t>>(SessionBlock::serialize(sess)); uuid::uuid uid, did, sid; sess.getSid(sid); sess.getUid(uid); sess.getDid(did); Loading @@ -435,18 +437,17 @@ namespace authdb { uint64_t sgid = sessionGroupId(uid, did); uint64_t sid_gid = sidGroupId(sid); if (!pclient_) return; // Distribute erasure-coded shards across peer nodes // Push in background thread so login response isn't blocked by timeouts std::thread([this, data, sgid, sid_gid]() { 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"); pclient_->store(sgid, data.data(), data.size()); pclient_->store(sid_gid, data.data(), data.size()); } catch (const netplus::NetException &e) { std::cerr << "Cluster push session failed: " << e.what() << std::endl; std::unique_lock<std::timed_mutex> lock(client_mutex_, std::chrono::seconds(5)); if (!lock.owns_lock()) return; pclient_->store(sgid, data->data(), data->size()); pclient_->store(sid_gid, data->data(), data->size()); } catch (const std::exception &e) { std::cerr << "Cluster push session failed: " << e.what() << std::endl; std::cerr << "Cluster push session (bg): " << e.what() << std::endl; } }).detach(); } bool Cluster::fetchSession(const uuid::uuid &uid, const uuid::uuid &did, Loading
src/session.cpp +2 −4 Original line number Diff line number Diff line Loading @@ -532,11 +532,9 @@ const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid session cur->_members = c_members; cur->_username = c_username; cur->setGPOResults(c_gpo); } else { // Session removed on another node — purge local copy removeLocal(sessionid); return nullptr; } // If fetch fails (peers unreachable), just use the local session as-is. // Do NOT remove — the session is valid locally even if cluster is down. } return cur; } Loading