Loading src/admin.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -2015,6 +2015,36 @@ namespace authdb { throw AuthBackendError("No Session found!"); } } catch (...) { // If cluster is critical (< k nodes), show warning page with auto-refresh if (g_Cluster && g_Cluster->isCritical()) { const char *warn_html = "<!DOCTYPE html><html><head>" "<meta http-equiv=\"refresh\" content=\"10\">" "<meta charset=\"utf-8\">" "<title>Cluster nicht bereit</title>" "<style>" "body{font-family:sans-serif;display:flex;justify-content:center;" "align-items:center;min-height:100vh;margin:0;background:#1a1a2e;color:#e0e0e0}" ".box{text-align:center;background:#16213e;padding:40px 60px;border-radius:12px;" "box-shadow:0 4px 20px rgba(0,0,0,0.4)}" ".spinner{border:4px solid #333;border-top:4px solid #e94560;border-radius:50%;" "width:40px;height:40px;animation:spin 1s linear infinite;margin:20px auto}" "@keyframes spin{to{transform:rotate(360deg)}}" "h2{color:#e94560;margin-bottom:10px}" "p{color:#a0a0a0}" "</style></head><body>" "<div class=\"box\">" "<div class=\"spinner\"></div>" "<h2>Cluster nicht bereit</h2>" "<p>Zu wenig Nodes erreichbar. Warte auf Cluster-Wiederherstellung…</p>" "<p style=\"font-size:0.8em\">Seite wird alle 10 Sekunden aktualisiert.</p>" "</div></body></html>"; libhttppp::HttpResponse rep; rep.setState(HTTP503); rep.setContentType("text/html"); rep.send(curreq, warn_html, strlen(warn_html)); return; } try { login(curreq, tid, args); return; Loading src/cluster.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -516,21 +516,25 @@ namespace authdb { << " nodes online" << std::endl; degraded_ = false; } critical_ = false; } else if (health.nodes_online >= k) { if (!degraded_) { std::cerr << "Cluster: DEGRADED — " << health.nodes_online << "/" << n << " nodes online" << std::endl; } degraded_ = true; critical_ = false; } else { std::cerr << "Cluster: CRITICAL — only " << health.nodes_online << "/" << n << " nodes online (need " << k << ")" << std::endl; degraded_ = true; critical_ = true; } } catch (const std::exception &e) { std::cerr << "Cluster: health probe failed: " << e.what() << std::endl; degraded_ = true; critical_ = true; } } } Loading src/cluster.h +2 −0 Original line number Diff line number Diff line Loading @@ -206,11 +206,13 @@ namespace authdb { void listAllSessions(std::vector<SessionInfo> &out); bool isDegraded() const { return degraded_; } bool isCritical() const { return critical_; } private: ClusterConfig cfg_; std::atomic<bool> running_{false}; std::atomic<bool> degraded_{false}; std::atomic<bool> critical_{false}; std::thread server_thread_; std::thread health_monitor_thread_; std::thread push_worker_thread_; Loading Loading
src/admin.cpp +30 −0 Original line number Diff line number Diff line Loading @@ -2015,6 +2015,36 @@ namespace authdb { throw AuthBackendError("No Session found!"); } } catch (...) { // If cluster is critical (< k nodes), show warning page with auto-refresh if (g_Cluster && g_Cluster->isCritical()) { const char *warn_html = "<!DOCTYPE html><html><head>" "<meta http-equiv=\"refresh\" content=\"10\">" "<meta charset=\"utf-8\">" "<title>Cluster nicht bereit</title>" "<style>" "body{font-family:sans-serif;display:flex;justify-content:center;" "align-items:center;min-height:100vh;margin:0;background:#1a1a2e;color:#e0e0e0}" ".box{text-align:center;background:#16213e;padding:40px 60px;border-radius:12px;" "box-shadow:0 4px 20px rgba(0,0,0,0.4)}" ".spinner{border:4px solid #333;border-top:4px solid #e94560;border-radius:50%;" "width:40px;height:40px;animation:spin 1s linear infinite;margin:20px auto}" "@keyframes spin{to{transform:rotate(360deg)}}" "h2{color:#e94560;margin-bottom:10px}" "p{color:#a0a0a0}" "</style></head><body>" "<div class=\"box\">" "<div class=\"spinner\"></div>" "<h2>Cluster nicht bereit</h2>" "<p>Zu wenig Nodes erreichbar. Warte auf Cluster-Wiederherstellung…</p>" "<p style=\"font-size:0.8em\">Seite wird alle 10 Sekunden aktualisiert.</p>" "</div></body></html>"; libhttppp::HttpResponse rep; rep.setState(HTTP503); rep.setContentType("text/html"); rep.send(curreq, warn_html, strlen(warn_html)); return; } try { login(curreq, tid, args); return; Loading
src/cluster.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -516,21 +516,25 @@ namespace authdb { << " nodes online" << std::endl; degraded_ = false; } critical_ = false; } else if (health.nodes_online >= k) { if (!degraded_) { std::cerr << "Cluster: DEGRADED — " << health.nodes_online << "/" << n << " nodes online" << std::endl; } degraded_ = true; critical_ = false; } else { std::cerr << "Cluster: CRITICAL — only " << health.nodes_online << "/" << n << " nodes online (need " << k << ")" << std::endl; degraded_ = true; critical_ = true; } } catch (const std::exception &e) { std::cerr << "Cluster: health probe failed: " << e.what() << std::endl; degraded_ = true; critical_ = true; } } } Loading
src/cluster.h +2 −0 Original line number Diff line number Diff line Loading @@ -206,11 +206,13 @@ namespace authdb { void listAllSessions(std::vector<SessionInfo> &out); bool isDegraded() const { return degraded_; } bool isCritical() const { return critical_; } private: ClusterConfig cfg_; std::atomic<bool> running_{false}; std::atomic<bool> degraded_{false}; std::atomic<bool> critical_{false}; std::thread server_thread_; std::thread health_monitor_thread_; std::thread push_worker_thread_; Loading