Commit 88f614c4 authored by jan.koester's avatar jan.koester
Browse files

test

parent 2e55d42a
Loading
Loading
Loading
Loading
Loading
+2 −7
Changes for src/authdb.cpp: 2 added lines, 7 removed lines.
Original line number Diff line number Diff line
@@ -254,7 +254,6 @@ namespace authdb {
                }

                if(curreq.getRequestURL().compare(0,9,"/settings",9)==0){
                    AuthBackendLock admlock(_AdminBackend);
                    try{
                        _AdminInterface.Request(curreq,tid,args);
                        g_Log.access(clientAddr,method,curreq.getRequestURL(),200);
@@ -346,7 +345,6 @@ namespace authdb {
                        rep.send(curreq,"uuid not found!",12);
                    }
                }else if(curreq.getRequestURL().compare(0,10,"/getavatar",10)==0){
                    AuthBackendLock admlock(_AdminBackend);
                    try{
                        getAvatar(curreq,tid,args);
                        g_Log.access(clientAddr,method,curreq.getRequestURL(),200);
@@ -402,11 +400,8 @@ namespace authdb {

            ::uuid::uuid uid(cuid);

            // Lock the domain backend if different from admin (admin already locked by caller)
            std::unique_ptr<AuthBackendLock> domlock;
            if (backend != &_AdminBackend) {
                domlock = std::make_unique<AuthBackendLock>(*backend);
            }
            // Always lock the resolved backend
            AuthBackendLock domlock(*backend);

            size_t rd=sizeof(authdb::AuthHeader),end=backend->end();

+22 −13
Changes for src/backends/cluster.cpp: 22 added lines, 13 removed lines.
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ namespace authdb {
        auto now = std::chrono::steady_clock::now();
        bool do_peer_fetch = (now - _LastPeerFetch) >= std::chrono::seconds(5);

        // Network I/O runs WITHOUT _BufMtx to avoid blocking other threads
        if (do_peer_fetch) {
            auto &client = g_Cluster->getClient();
            if (client) {
@@ -95,6 +96,9 @@ namespace authdb {
            }
        }

        // Only hold _BufMtx for the buffer merge — no network I/O here
        std::lock_guard<std::mutex> guard(_BufMtx);

        // Pick the buffer with the highest revision (most recent writes)
        size_t local_rev = bufferRevision(local_data);
        size_t peer_rev  = bufferRevision(peer_data);
@@ -129,32 +133,39 @@ namespace authdb {
            std::cerr << "ClusterBackend::pushToCluster: cluster not available" << std::endl;
            return;
        }

        // Copy buffer and state under _BufMtx, then release before network I/O
        std::vector<uint8_t> buf_copy;
        uint64_t dgid;
        {
            std::lock_guard<std::mutex> guard(_BufMtx);
            if (!_Dirty) {
                return;
            }

            // Bump revision so peers can detect newer data
            newRevesion();

        uint64_t dgid = domainGroupId();
            dgid = domainGroupId();
            buf_copy = _Buffer;
            _Dirty = false;
        }

        // Store in local block store (file or memory backed)
        auto &store = g_Cluster->getStore();
        if (!store.store(dgid, 0, _Buffer.data(), _Buffer.size())) {
        if (!store.store(dgid, 0, buf_copy.data(), buf_copy.size())) {
            std::cerr << "ClusterBackend::pushToCluster: store.store() failed for group "
                      << std::hex << dgid << std::dec
                      << " (domain=" << _Domain << " bufsize=" << _Buffer.size() << ")"
                      << " (domain=" << _Domain << " bufsize=" << buf_copy.size() << ")"
                      << std::endl;
        }

        // Replicate raw data to all peer nodes
        // Replicate raw data to all peer nodes — no _BufMtx held
        auto &client = g_Cluster->getClient();
        if (client) {
            try {
                auto &cmtx = g_Cluster->getClientMutex();
                std::unique_lock<std::timed_mutex> lock(cmtx, std::chrono::seconds(3));
                if (lock.owns_lock()) {
                    client->replicate_to_peers(dgid, 0, _Buffer.data(), _Buffer.size());
                    client->replicate_to_peers(dgid, 0, buf_copy.data(), buf_copy.size());
                } else {
                    std::cerr << "ClusterBackend::pushToCluster: skipped replication (lock busy)" << std::endl;
                }
@@ -164,8 +175,6 @@ namespace authdb {
                std::cerr << "Cluster replicate failed: " << e.what() << std::endl;
            }
        }

        _Dirty = false;
    }

    ClusterBackend::ClusterBackend(const char *domain, size_t version, const char *filepath)
@@ -224,14 +233,14 @@ namespace authdb {
    }

    void ClusterBackend::lock() {
        // Network I/O: fetch latest data from cluster peers.
        // _BufMtx serializes concurrent fetch/push so _Buffer is safe.
        std::lock_guard<std::mutex> guard(_BufMtx);
        // fetchFromCluster handles _BufMtx internally — only during buffer merge,
        // NOT during network I/O, so other threads aren't blocked.
        fetchFromCluster();
    }

    void ClusterBackend::unlock() {
        std::lock_guard<std::mutex> guard(_BufMtx);
        // pushToCluster handles _BufMtx internally — copies buffer under lock,
        // then does network I/O without holding it.
        pushToCluster();
    }