Commit a0632403 authored by jan.koester's avatar jan.koester
Browse files

test

parent b949e037
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
mediadb (20260419+28) unstable; urgency=critical

  * Fix cluster startup deadlock: initial_sync_ok_ was only set on empty 
    clusters but never after a successful index fetch, causing all nodes 
    with real data to remain permanently locked in "syncing" state (5/5 
    incomplete). Now properly set after load_index_from_buffer succeeds.

 -- Jan Koester <jan.koester@tuxist.de>  Sun, 19 Apr 2026 16:15:00 +0200

mediadb (20260419+27) unstable; urgency=critical

  * Fix catastrophic cluster data loss ("stores disappeared") caused by nodes 
+13 −14
Original line number Diff line number Diff line
@@ -2436,18 +2436,15 @@ void ClusterMediaBackend::start_sync() {
    // to become fully available even after waitForPeers returns.
    for (int attempt = 1; attempt <= 5; ++attempt) {
        sync_from_cluster();
        {
        if (initial_sync_ok_.load()) {
            std::shared_lock<std::shared_mutex> cguard(cluster_op_mutex_);
            auto sids = local_.store_ids();
            if (!sids.empty()) {
                // Count total albums across all stores
            std::size_t total_albums = 0;
            for (const auto& sid : sids)
                total_albums += local_.list_albums(sid).size();
            std::cerr << "[CLUSTER-SYNC] initial sync OK on attempt " << attempt
                      << ": " << sids.size() << " stores, " << total_albums << " albums\n";
                if (total_albums > 0) break;  // fully synced
            }
            break;
        }
        std::cerr << "[CLUSTER-SYNC] initial sync attempt " << attempt
                  << "/5 incomplete, retrying in 2s\n";
@@ -2999,19 +2996,21 @@ void ClusterMediaBackend::sync_from_cluster() {
    bool fetch_ok = cluster_.fetch("index", index_data);
    if (!fetch_ok || index_data.empty()) {
        if (!has_index) {
            std::cerr << "[CLUSTER-SYNC] fresh empty cluster detected\n";
            std::cerr << "[CLUSTER-SYNC] no index exists on any peer — fresh/empty cluster\n";
            initial_sync_ok_.store(true);
        } else {
            std::cerr << "[CLUSTER-SYNC] index fetch "
                      << (fetch_ok ? "returned empty data" : "failed (exception in cluster layer)")
                  << "\n";
                      << " (has_index=true, peers report having group)\n";
        }
        return;
    }
    std::cerr << "[CLUSTER-SYNC] index fetched OK, " << index_data.size() << " bytes\n";
    {
        std::unique_lock<std::shared_mutex> cguard(cluster_op_mutex_);
        local_.load_index_from_buffer(index_data);
    }
    initial_sync_ok_.store(true);

    // Snapshot store IDs under shared lock
    std::vector<std::string> sids;