//------------------------------------------------------------------------------ /* This file is part of clio: https://github.com/XRPLF/clio Copyright (c) 2026, the clio developers. Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ //============================================================================== #pragma once #include "cluster/Backend.hpp" #include "cluster/ClioNode.hpp" #include "data/LedgerCacheLoadingState.hpp" #include #include namespace cluster { /** * @brief Decides which node in the cluster should load the ledger cache. * * This class monitors cluster state changes and determines whether the current node * should begin loading the ledger cache from the backend. The decision is made by: * 1. Doing nothing if this node's cache is already full * 2. Doing nothing if any node in the cluster is currently loading the cache * 3. Sorting all nodes whose cache is not yet full by UUID for deterministic ordering * 4. Permitting loading on this node if it is the first in the sorted list * * This ensures at most one node in the cluster loads the cache at a time. */ class CacheLoaderDecider { /** @brief Thread pool for spawning asynchronous tasks */ boost::asio::thread_pool& ctx_; /** @brief Interface for controlling cache loading permission of this node */ std::unique_ptr cacheLoadingState_; public: /** * @brief Constructs a CacheLoaderDecider. * * @param ctx Thread pool for executing asynchronous operations * @param cacheLoadingState Cache loading state interface for permitting cache load */ CacheLoaderDecider( boost::asio::thread_pool& ctx, std::unique_ptr cacheLoadingState ); /** * @brief Handles cluster state changes and decides whether this node should load the cache. * * This method is called when cluster state changes. It asynchronously: * - Does nothing if this node's cache is already full * - Does nothing if any node in the cluster is currently loading the cache * - Sorts all not-yet-full nodes by UUID to establish a deterministic order * - Permits cache loading on this node if it is first in the sorted list * * @param selfId The UUID of the current node * @param clusterData Shared pointer to current cluster data; may be empty if communication * failed */ void onNewState(ClioNode::CUuid selfId, std::shared_ptr clusterData); }; } // namespace cluster