Loading src/session.cpp +25 −114 Changes for src/session.cpp: 25 added lines, 114 removed lines. Original line number Diff line number Diff line Loading @@ -419,15 +419,13 @@ authdb::ClusterSession::ClusterSession() : LocalSession() {} authdb::ClusterSession::~ClusterSession() {} const authdb::SessionData *authdb::ClusterSession::addSession(AuthBackend &backend,uuid::uuid domainid,uuid::uuid userid){ // Reject if cluster is not available — session would not replicate if (!g_Cluster || !g_Cluster->isRunning()) { if (!g_Cluster || !g_Cluster->isRunning()) throw AuthBackendError("cluster not ready — please try again later"); } else if (g_Cluster->isCritical()) { if (g_Cluster->isCritical()) throw AuthBackendError("cluster critical — too few nodes online, please try again later"); } // Check cluster for existing session if (g_Cluster && g_Cluster->isRunning()) { // Check cluster for existing session (same user+domain) { uuid::uuid cluster_sid; std::vector<uuid::uuid> cluster_members; std::string cluster_username; Loading @@ -437,9 +435,7 @@ const authdb::SessionData *authdb::ClusterSession::addSession(AuthBackend &backe SessionData *imported = new SessionData(cluster_sid, userid, domainid, cluster_members); imported->_username = cluster_username; imported->setGPOResults(cluster_gpo); std::lock_guard<std::mutex> guard(_lock); // Replace any stale cache entry removeLocal(cluster_sid); appendLocal(imported); return imported; Loading @@ -454,86 +450,31 @@ const authdb::SessionData *authdb::ClusterSession::addSession(AuthBackend &backe std::cerr << "[SESSION] addSession: created sid=" << newSid.c_str() << " uid=" << userid.c_str() << " did=" << domainid.c_str() << std::endl; // Synchronous push to cluster with retry — re-push if verify fails if (g_Cluster && g_Cluster->isRunning()) { bool verified = false; int push_retries = 3; for (int retry = 0; retry < push_retries && !verified; ++retry) { // Push to cluster try { g_Cluster->pushSession(*newSession); std::cerr << "[SESSION] addSession: pushSession attempt " << (retry+1) << " OK" << std::endl; std::cerr << "[SESSION] addSession: pushSession OK" << std::endl; } catch (const std::exception &e) { std::cerr << "[SESSION] addSession: pushSession attempt " << (retry+1) << " FAILED: " << e.what() << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(200)); continue; } // Verify session is retrievable from cluster auto verify_deadline = std::chrono::steady_clock::now() + std::chrono::seconds(2); int checks = 0; while (std::chrono::steady_clock::now() < verify_deadline) { ++checks; uuid::uuid v_sid, v_uid, v_did; std::vector<uuid::uuid> v_members; std::string v_username; std::vector<std::pair<uuid::uuid, bool>> v_gpo; if (g_Cluster->fetchSessionBySid(newSid, v_sid, v_uid, v_did, v_members, v_username, v_gpo)) { std::cerr << "[SESSION] addSession: verified on attempt " << (retry+1) << " after " << checks << " check(s)" << std::endl; verified = true; break; } std::this_thread::sleep_for(std::chrono::milliseconds(150)); } if (!verified) { std::cerr << "[SESSION] addSession: verify FAILED on attempt " << (retry+1) << " after " << checks << " checks — will retry push" << std::endl; } } if (!verified) { std::cerr << "[SESSION] addSession: ERROR — session not verifiable after " << push_retries << " push attempts" << std::endl; std::cerr << "[SESSION] addSession: pushSession FAILED: " << e.what() << std::endl; delete newSession; throw AuthBackendError("session could not be stored in cluster — please try again"); } } // Keep pointer alive for callers { std::lock_guard<std::mutex> guard(_lock); appendLocal(newSession); } return newSession; } const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid sessionid){ // Reject if cluster is not available if (!g_Cluster || !g_Cluster->isRunning()) { throw AuthBackendError("cluster not ready — please try again later"); } else if (g_Cluster->isCritical()) { throw AuthBackendError("cluster critical — too few nodes online, please try again later"); } // Check temp cache first (TTL 5 seconds) { std::lock_guard<std::mutex> guard(_lock); cleanupExpired(); SessionData *cur = findLocal(sessionid); if (cur) { auto age = std::chrono::duration_cast<std::chrono::seconds>( std::chrono::steady_clock::now() - cur->_lastClusterSync).count(); if (age < 5) return cur; } } if (!g_Cluster || !g_Cluster->isRunning()) return nullptr; if (g_Cluster->isCritical()) return nullptr; // Single cluster fetch — no long retry loop to avoid blocking the API response if (g_Cluster && g_Cluster->isRunning()) { // Fetch directly from cluster — single source of truth uuid::uuid sid, uid, did; std::vector<uuid::uuid> members; std::string username; Loading @@ -542,8 +483,6 @@ const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid session SessionData *imported = new SessionData(sid, uid, did, members); imported->_username = username; imported->setGPOResults(gpo_results); imported->_lastClusterSync = std::chrono::steady_clock::now(); std::lock_guard<std::mutex> guard(_lock); removeLocal(sessionid); appendLocal(imported); Loading @@ -552,78 +491,51 @@ const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid session std::cerr << "[SESSION] getSession: sid=" << sessionid.c_str() << " not found in cluster" << std::endl; // Return stale cache if available — and lazily push it to the cluster // so other nodes can find it (heals sessions from before cluster code) std::lock_guard<std::mutex> guard(_lock); SessionData *stale = findLocal(sessionid); if (stale) { std::cerr << "[SESSION] getSession: found stale local session, pushing to cluster (lazy heal)" << std::endl; try { g_Cluster->pushSession(*stale); } catch (...) { std::cerr << "[SESSION] getSession: lazy heal push failed" << std::endl; } stale->_lastClusterSync = std::chrono::steady_clock::now(); return stale; } } return nullptr; } void authdb::ClusterSession::remSession(uuid::uuid sessionid){ // Remove from cluster if (g_Cluster && g_Cluster->isRunning()) { try { g_Cluster->removeSessionBySid(sessionid); } catch (...) {} } // Remove from temp cache std::lock_guard<std::mutex> guard(_lock); removeLocal(sessionid); } void authdb::ClusterSession::relSession(AuthBackend &backend,uuid::uuid sessionid){ // Fetch current session from cluster SessionData *cursess = nullptr; if (!g_Cluster || !g_Cluster->isRunning()) throw AuthBackendError("reload session: cluster not available"); if (g_Cluster && g_Cluster->isRunning()) { // Fetch from cluster uuid::uuid sid, uid, did; std::vector<uuid::uuid> members; std::string c_username; std::vector<std::pair<uuid::uuid, bool>> gpo_results; if (g_Cluster->fetchSessionBySid(sessionid, sid, uid, did, members, c_username, gpo_results)) { cursess = new SessionData(sid, uid, did, members); if (!g_Cluster->fetchSessionBySid(sessionid, sid, uid, did, members, c_username, gpo_results)) throw AuthBackendError("reload session: sessionid not found !"); SessionData *cursess = new SessionData(sid, uid, did, members); cursess->_username = c_username; cursess->setGPOResults(gpo_results); std::lock_guard<std::mutex> guard(_lock); removeLocal(sessionid); appendLocal(cursess); } } if (!cursess) throw AuthBackendError("reload session: sessionid not found !"); { std::lock_guard<std::mutex> guard(_lock); reloadSessionData(backend, cursess); } // Push updated data back to cluster if (g_Cluster && g_Cluster->isRunning()) { try { g_Cluster->pushSession(*cursess); } catch (...) {} } std::lock_guard<std::mutex> guard(_lock); removeLocal(sessionid); appendLocal(cursess); } void authdb::ClusterSession::listSessions(std::vector<SessionInfo> &out){ out.clear(); if (!g_Cluster || !g_Cluster->isRunning()) return; // Always from cluster — single source of truth if (g_Cluster && g_Cluster->isRunning()) { std::vector<Cluster::SessionInfo> csessions; g_Cluster->listAllSessions(csessions); for (const auto &cs : csessions) { Loading @@ -635,4 +547,3 @@ void authdb::ClusterSession::listSessions(std::vector<SessionInfo> &out){ out.push_back(std::move(info)); } } } Loading
src/session.cpp +25 −114 Changes for src/session.cpp: 25 added lines, 114 removed lines. Original line number Diff line number Diff line Loading @@ -419,15 +419,13 @@ authdb::ClusterSession::ClusterSession() : LocalSession() {} authdb::ClusterSession::~ClusterSession() {} const authdb::SessionData *authdb::ClusterSession::addSession(AuthBackend &backend,uuid::uuid domainid,uuid::uuid userid){ // Reject if cluster is not available — session would not replicate if (!g_Cluster || !g_Cluster->isRunning()) { if (!g_Cluster || !g_Cluster->isRunning()) throw AuthBackendError("cluster not ready — please try again later"); } else if (g_Cluster->isCritical()) { if (g_Cluster->isCritical()) throw AuthBackendError("cluster critical — too few nodes online, please try again later"); } // Check cluster for existing session if (g_Cluster && g_Cluster->isRunning()) { // Check cluster for existing session (same user+domain) { uuid::uuid cluster_sid; std::vector<uuid::uuid> cluster_members; std::string cluster_username; Loading @@ -437,9 +435,7 @@ const authdb::SessionData *authdb::ClusterSession::addSession(AuthBackend &backe SessionData *imported = new SessionData(cluster_sid, userid, domainid, cluster_members); imported->_username = cluster_username; imported->setGPOResults(cluster_gpo); std::lock_guard<std::mutex> guard(_lock); // Replace any stale cache entry removeLocal(cluster_sid); appendLocal(imported); return imported; Loading @@ -454,86 +450,31 @@ const authdb::SessionData *authdb::ClusterSession::addSession(AuthBackend &backe std::cerr << "[SESSION] addSession: created sid=" << newSid.c_str() << " uid=" << userid.c_str() << " did=" << domainid.c_str() << std::endl; // Synchronous push to cluster with retry — re-push if verify fails if (g_Cluster && g_Cluster->isRunning()) { bool verified = false; int push_retries = 3; for (int retry = 0; retry < push_retries && !verified; ++retry) { // Push to cluster try { g_Cluster->pushSession(*newSession); std::cerr << "[SESSION] addSession: pushSession attempt " << (retry+1) << " OK" << std::endl; std::cerr << "[SESSION] addSession: pushSession OK" << std::endl; } catch (const std::exception &e) { std::cerr << "[SESSION] addSession: pushSession attempt " << (retry+1) << " FAILED: " << e.what() << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(200)); continue; } // Verify session is retrievable from cluster auto verify_deadline = std::chrono::steady_clock::now() + std::chrono::seconds(2); int checks = 0; while (std::chrono::steady_clock::now() < verify_deadline) { ++checks; uuid::uuid v_sid, v_uid, v_did; std::vector<uuid::uuid> v_members; std::string v_username; std::vector<std::pair<uuid::uuid, bool>> v_gpo; if (g_Cluster->fetchSessionBySid(newSid, v_sid, v_uid, v_did, v_members, v_username, v_gpo)) { std::cerr << "[SESSION] addSession: verified on attempt " << (retry+1) << " after " << checks << " check(s)" << std::endl; verified = true; break; } std::this_thread::sleep_for(std::chrono::milliseconds(150)); } if (!verified) { std::cerr << "[SESSION] addSession: verify FAILED on attempt " << (retry+1) << " after " << checks << " checks — will retry push" << std::endl; } } if (!verified) { std::cerr << "[SESSION] addSession: ERROR — session not verifiable after " << push_retries << " push attempts" << std::endl; std::cerr << "[SESSION] addSession: pushSession FAILED: " << e.what() << std::endl; delete newSession; throw AuthBackendError("session could not be stored in cluster — please try again"); } } // Keep pointer alive for callers { std::lock_guard<std::mutex> guard(_lock); appendLocal(newSession); } return newSession; } const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid sessionid){ // Reject if cluster is not available if (!g_Cluster || !g_Cluster->isRunning()) { throw AuthBackendError("cluster not ready — please try again later"); } else if (g_Cluster->isCritical()) { throw AuthBackendError("cluster critical — too few nodes online, please try again later"); } // Check temp cache first (TTL 5 seconds) { std::lock_guard<std::mutex> guard(_lock); cleanupExpired(); SessionData *cur = findLocal(sessionid); if (cur) { auto age = std::chrono::duration_cast<std::chrono::seconds>( std::chrono::steady_clock::now() - cur->_lastClusterSync).count(); if (age < 5) return cur; } } if (!g_Cluster || !g_Cluster->isRunning()) return nullptr; if (g_Cluster->isCritical()) return nullptr; // Single cluster fetch — no long retry loop to avoid blocking the API response if (g_Cluster && g_Cluster->isRunning()) { // Fetch directly from cluster — single source of truth uuid::uuid sid, uid, did; std::vector<uuid::uuid> members; std::string username; Loading @@ -542,8 +483,6 @@ const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid session SessionData *imported = new SessionData(sid, uid, did, members); imported->_username = username; imported->setGPOResults(gpo_results); imported->_lastClusterSync = std::chrono::steady_clock::now(); std::lock_guard<std::mutex> guard(_lock); removeLocal(sessionid); appendLocal(imported); Loading @@ -552,78 +491,51 @@ const authdb::SessionData *authdb::ClusterSession::getSession(uuid::uuid session std::cerr << "[SESSION] getSession: sid=" << sessionid.c_str() << " not found in cluster" << std::endl; // Return stale cache if available — and lazily push it to the cluster // so other nodes can find it (heals sessions from before cluster code) std::lock_guard<std::mutex> guard(_lock); SessionData *stale = findLocal(sessionid); if (stale) { std::cerr << "[SESSION] getSession: found stale local session, pushing to cluster (lazy heal)" << std::endl; try { g_Cluster->pushSession(*stale); } catch (...) { std::cerr << "[SESSION] getSession: lazy heal push failed" << std::endl; } stale->_lastClusterSync = std::chrono::steady_clock::now(); return stale; } } return nullptr; } void authdb::ClusterSession::remSession(uuid::uuid sessionid){ // Remove from cluster if (g_Cluster && g_Cluster->isRunning()) { try { g_Cluster->removeSessionBySid(sessionid); } catch (...) {} } // Remove from temp cache std::lock_guard<std::mutex> guard(_lock); removeLocal(sessionid); } void authdb::ClusterSession::relSession(AuthBackend &backend,uuid::uuid sessionid){ // Fetch current session from cluster SessionData *cursess = nullptr; if (!g_Cluster || !g_Cluster->isRunning()) throw AuthBackendError("reload session: cluster not available"); if (g_Cluster && g_Cluster->isRunning()) { // Fetch from cluster uuid::uuid sid, uid, did; std::vector<uuid::uuid> members; std::string c_username; std::vector<std::pair<uuid::uuid, bool>> gpo_results; if (g_Cluster->fetchSessionBySid(sessionid, sid, uid, did, members, c_username, gpo_results)) { cursess = new SessionData(sid, uid, did, members); if (!g_Cluster->fetchSessionBySid(sessionid, sid, uid, did, members, c_username, gpo_results)) throw AuthBackendError("reload session: sessionid not found !"); SessionData *cursess = new SessionData(sid, uid, did, members); cursess->_username = c_username; cursess->setGPOResults(gpo_results); std::lock_guard<std::mutex> guard(_lock); removeLocal(sessionid); appendLocal(cursess); } } if (!cursess) throw AuthBackendError("reload session: sessionid not found !"); { std::lock_guard<std::mutex> guard(_lock); reloadSessionData(backend, cursess); } // Push updated data back to cluster if (g_Cluster && g_Cluster->isRunning()) { try { g_Cluster->pushSession(*cursess); } catch (...) {} } std::lock_guard<std::mutex> guard(_lock); removeLocal(sessionid); appendLocal(cursess); } void authdb::ClusterSession::listSessions(std::vector<SessionInfo> &out){ out.clear(); if (!g_Cluster || !g_Cluster->isRunning()) return; // Always from cluster — single source of truth if (g_Cluster && g_Cluster->isRunning()) { std::vector<Cluster::SessionInfo> csessions; g_Cluster->listAllSessions(csessions); for (const auto &cs : csessions) { Loading @@ -635,4 +547,3 @@ void authdb::ClusterSession::listSessions(std::vector<SessionInfo> &out){ out.push_back(std::move(info)); } } }