Loading src/authdb.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -685,6 +685,13 @@ int main(int argc,char *argv[]){ authdb::g_Cluster = &cluster; std::cerr << "Cluster started on " << ccfg.bind_address << ":" << ccfg.port << " with " << ccfg.peers.size() << " peer(s)" << std::endl; // Wait for peers to become reachable before constructing backends. // This ensures fetchFromCluster() in ClusterBackend can retrieve data. size_t online = cluster.waitForPeers(120); if (online == 0) { std::cerr << "Cluster: no peers reachable, cannot start. Exiting." << std::endl; return 1; } } // Instantiate session store: cluster-aware or local-only Loading src/cluster.cpp +37 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,43 @@ namespace authdb { server_thread_ = std::thread(&Cluster::server_loop, this); } size_t Cluster::waitForPeers(int timeout_s) { if (!pclient_) return 0; size_t k = cfg_.data_blocks; size_t n = cfg_.data_blocks + cfg_.parity_blocks; size_t best_online = 0; for (int elapsed = 0; elapsed < timeout_s; ++elapsed) { try { auto &cmtx = getClientMutex(); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(2)); if (lock.owns_lock()) { auto health = pclient_->get_cluster_status(); if (health.nodes_online > best_online) best_online = health.nodes_online; std::cerr << "Cluster: " << health.nodes_online << "/" << health.nodes_total << " nodes online (" << elapsed << "s/" << timeout_s << "s)" << std::endl; if (health.nodes_online >= n) { std::cerr << "Cluster: all nodes online" << std::endl; return health.nodes_online; } if (health.nodes_online >= k) { std::cerr << "Cluster: DEGRADED — " << health.nodes_online << "/" << n << " nodes online, continuing" << std::endl; return health.nodes_online; } } } catch (const std::exception &e) { std::cerr << "Cluster: peer probe failed: " << e.what() << std::endl; } std::this_thread::sleep_for(std::chrono::seconds(1)); } std::cerr << "Cluster: FAILED — only " << best_online << "/" << n << " nodes reachable after " << timeout_s << "s (need " << k << ")" << std::endl; return best_online; } void Cluster::stop() { if (!running_) return; running_ = false; Loading src/cluster.h +4 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,10 @@ namespace authdb { bool isRunning() const { return running_; } // Block until at least k nodes are reachable (up to timeout_s seconds). // Returns number of nodes online. size_t waitForPeers(int timeout_s = 10); // Accessors for backend use paritypp::block_store &getStore() { return *store_; } std::unique_ptr<paritypp::client> &getClient() { return pclient_; } Loading Loading
src/authdb.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -685,6 +685,13 @@ int main(int argc,char *argv[]){ authdb::g_Cluster = &cluster; std::cerr << "Cluster started on " << ccfg.bind_address << ":" << ccfg.port << " with " << ccfg.peers.size() << " peer(s)" << std::endl; // Wait for peers to become reachable before constructing backends. // This ensures fetchFromCluster() in ClusterBackend can retrieve data. size_t online = cluster.waitForPeers(120); if (online == 0) { std::cerr << "Cluster: no peers reachable, cannot start. Exiting." << std::endl; return 1; } } // Instantiate session store: cluster-aware or local-only Loading
src/cluster.cpp +37 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,43 @@ namespace authdb { server_thread_ = std::thread(&Cluster::server_loop, this); } size_t Cluster::waitForPeers(int timeout_s) { if (!pclient_) return 0; size_t k = cfg_.data_blocks; size_t n = cfg_.data_blocks + cfg_.parity_blocks; size_t best_online = 0; for (int elapsed = 0; elapsed < timeout_s; ++elapsed) { try { auto &cmtx = getClientMutex(); std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(2)); if (lock.owns_lock()) { auto health = pclient_->get_cluster_status(); if (health.nodes_online > best_online) best_online = health.nodes_online; std::cerr << "Cluster: " << health.nodes_online << "/" << health.nodes_total << " nodes online (" << elapsed << "s/" << timeout_s << "s)" << std::endl; if (health.nodes_online >= n) { std::cerr << "Cluster: all nodes online" << std::endl; return health.nodes_online; } if (health.nodes_online >= k) { std::cerr << "Cluster: DEGRADED — " << health.nodes_online << "/" << n << " nodes online, continuing" << std::endl; return health.nodes_online; } } } catch (const std::exception &e) { std::cerr << "Cluster: peer probe failed: " << e.what() << std::endl; } std::this_thread::sleep_for(std::chrono::seconds(1)); } std::cerr << "Cluster: FAILED — only " << best_online << "/" << n << " nodes reachable after " << timeout_s << "s (need " << k << ")" << std::endl; return best_online; } void Cluster::stop() { if (!running_) return; running_ = false; Loading
src/cluster.h +4 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,10 @@ namespace authdb { bool isRunning() const { return running_; } // Block until at least k nodes are reachable (up to timeout_s seconds). // Returns number of nodes online. size_t waitForPeers(int timeout_s = 10); // Accessors for backend use paritypp::block_store &getStore() { return *store_; } std::unique_ptr<paritypp::client> &getClient() { return pclient_; } Loading