mirror of
https://github.com/XRPLF/clio.git
synced 2026-06-04 01:06:45 +00:00
247 lines
8.3 KiB
C++
247 lines
8.3 KiB
C++
#pragma once
|
|
|
|
#include "data/LedgerCacheInterface.hpp"
|
|
#include "etl/SystemState.hpp"
|
|
#include "util/prometheus/Bool.hpp"
|
|
#include "util/prometheus/Label.hpp"
|
|
#include "util/prometheus/Prometheus.hpp"
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
namespace etl {
|
|
|
|
/**
|
|
* @brief Interface for managing writer state in the ETL subsystem.
|
|
*
|
|
* This interface provides methods to query and control whether the ETL process
|
|
* is actively writing to the database. Implementations should coordinate with
|
|
* the ETL system state to manage write responsibilities.
|
|
*/
|
|
class WriterStateInterface {
|
|
public:
|
|
virtual ~WriterStateInterface() = default;
|
|
|
|
/**
|
|
* @brief Check if the ETL process is in strict read-only mode.
|
|
* @return true if the process is in strict read-only mode, false otherwise
|
|
*/
|
|
[[nodiscard]] virtual bool
|
|
isReadOnly() const = 0;
|
|
|
|
/**
|
|
* @brief Check if the ETL process is currently writing to the database.
|
|
* @return true if the process is writing, false otherwise
|
|
*/
|
|
[[nodiscard]] virtual bool
|
|
isWriting() const = 0;
|
|
|
|
/**
|
|
* @brief Request to start writing to the database.
|
|
*
|
|
* This method signals that the process should take over writing responsibilities.
|
|
* The actual transition to writing state may not be immediate.
|
|
*/
|
|
virtual void
|
|
startWriting() = 0;
|
|
|
|
/**
|
|
* @brief Request to stop writing to the database.
|
|
*
|
|
* This method signals that the process should give up writing responsibilities.
|
|
* The actual transition from writing state may not be immediate.
|
|
*/
|
|
virtual void
|
|
giveUpWriting() = 0;
|
|
|
|
/**
|
|
* @brief Check if the cluster is using the fallback writer decision mechanism.
|
|
*
|
|
* @return true if the cluster has switched to fallback mode, false otherwise
|
|
*/
|
|
[[nodiscard]] virtual bool
|
|
isFallback() const = 0;
|
|
|
|
/**
|
|
* @brief Check if this node is in fallback recovery mode.
|
|
*
|
|
* Fallback recovery is an intermediate state entered when the node has been in
|
|
* fallback mode long enough to attempt returning to election-based writer selection.
|
|
* In this state the node continues participating in the fallback write-race while
|
|
* coordinating with other nodes to exit fallback together.
|
|
*
|
|
* @return true if the node is in fallback recovery mode, false otherwise
|
|
*/
|
|
[[nodiscard]] virtual bool
|
|
isFallbackRecovery() const = 0;
|
|
|
|
/**
|
|
* @brief Set or clear the fallback recovery flag.
|
|
*
|
|
* When @p newValue is true, the node enters fallback recovery mode:
|
|
* - @ref isFallbackRecovery returns true
|
|
* - The plain fallback flag (@ref isFallback) is cleared so the node no longer
|
|
* publishes @c DbRole::Fallback; it publishes @c DbRole::FallbackRecovery instead.
|
|
*
|
|
* When @p newValue is false, the recovery flag is cleared without touching the
|
|
* plain fallback flag. This is used when the recovery coordination completes and
|
|
* the node transitions back to election mode.
|
|
*
|
|
* @param newValue true to enter recovery mode, false to leave it
|
|
*/
|
|
virtual void
|
|
setFallbackRecovery(bool newValue) = 0;
|
|
|
|
/**
|
|
* @brief Switch the cluster to the fallback writer decision mechanism.
|
|
*
|
|
* This method is called when the cluster needs to transition from the cluster
|
|
* communication mechanism to the slower but more reliable fallback mechanism.
|
|
* Once set, this flag propagates to all nodes in the cluster through the
|
|
* ClioNode DbRole::Fallback state.
|
|
*
|
|
* Also clears the fallback recovery flag (@ref isFallbackRecovery) because entering
|
|
* a fresh fallback period cancels any in-progress recovery attempt.
|
|
*/
|
|
virtual void
|
|
setWriterDecidingFallback() = 0;
|
|
|
|
/**
|
|
* @brief Whether the ETL monitor has started and the node is ready to become a writer.
|
|
*
|
|
* @return true if ETL has started the monitor loop, false otherwise.
|
|
*/
|
|
[[nodiscard]] virtual bool
|
|
isEtlStarted() const = 0;
|
|
|
|
/**
|
|
* @brief Whether the ledger cache is fully loaded.
|
|
*
|
|
* @return true if the cache is full, false otherwise.
|
|
*/
|
|
[[nodiscard]] virtual bool
|
|
isCacheFull() const = 0;
|
|
|
|
/**
|
|
* @brief Create a clone of this writer state.
|
|
*
|
|
* Creates a new instance of the writer state with the same underlying system state.
|
|
* This is used when spawning operations that need their own writer state instance
|
|
* while sharing the same system state.
|
|
*
|
|
* @return A unique pointer to the cloned writer state.
|
|
*/
|
|
[[nodiscard]] virtual std::unique_ptr<WriterStateInterface>
|
|
clone() const = 0;
|
|
};
|
|
|
|
/**
|
|
* @brief Implementation of WriterStateInterface that manages ETL writer state.
|
|
*
|
|
* This class coordinates with SystemState to manage whether the ETL process
|
|
* is actively writing to the database. It provides methods to query the current
|
|
* writing state and request transitions between writing and non-writing states.
|
|
*/
|
|
class WriterState : public WriterStateInterface {
|
|
private:
|
|
std::shared_ptr<SystemState>
|
|
systemState_; /**< @brief Shared system state for ETL coordination */
|
|
std::reference_wrapper<data::LedgerCacheInterface const> cache_;
|
|
|
|
/**
|
|
* @brief Prometheus metric tracking whether this node is in fallback recovery mode.
|
|
*
|
|
* @note Because @c prometheus::Bool holds a @c std::reference_wrapper to the underlying
|
|
* gauge, copies of @c WriterState (including clones) share the same metric value.
|
|
* Mutations made through a clone are therefore immediately visible on the original
|
|
* instance and vice-versa.
|
|
*/
|
|
util::prometheus::Bool isFallbackRecovery_ = PrometheusService::boolMetric(
|
|
"etl_writing_deciding_fallback_recovery",
|
|
util::prometheus::Labels{},
|
|
"Whether clio is in recovery from the fallback writer decision mechanism"
|
|
);
|
|
|
|
public:
|
|
/**
|
|
* @brief Construct a WriterState with the given system state and cache.
|
|
*
|
|
* @param state Shared pointer to the system state for coordination
|
|
* @param cache The ledger cache used to report cache fullness
|
|
*/
|
|
WriterState(std::shared_ptr<SystemState> state, data::LedgerCacheInterface const& cache);
|
|
|
|
[[nodiscard]] bool
|
|
isReadOnly() const override;
|
|
|
|
/**
|
|
* @brief Check if the ETL process is currently writing to the database.
|
|
* @return true if the process is writing, false otherwise
|
|
*/
|
|
[[nodiscard]] bool
|
|
isWriting() const override;
|
|
|
|
/**
|
|
* @brief Request to start writing to the database.
|
|
*
|
|
* If already writing, this method does nothing. Otherwise, it sets the
|
|
* shouldTakeoverWriting flag in the system state to signal the request.
|
|
*/
|
|
void
|
|
startWriting() override;
|
|
|
|
/**
|
|
* @brief Request to stop writing to the database.
|
|
*
|
|
* If not currently writing, this method does nothing. Otherwise, it sets the
|
|
* shouldGiveUpWriter flag in the system state to signal the request.
|
|
*/
|
|
void
|
|
giveUpWriting() override;
|
|
|
|
/**
|
|
* @brief Switch the cluster to the fallback writer decision mechanism.
|
|
*
|
|
* Sets the isWriterDecidingFallback flag in the system state, which will be
|
|
* propagated to other nodes in the cluster through the ClioNode DbRole::Fallback state.
|
|
*/
|
|
void
|
|
setWriterDecidingFallback() override;
|
|
|
|
/**
|
|
* @brief Check if the cluster is using the fallback writer decision mechanism.
|
|
*
|
|
* @return true if the cluster has switched to fallback mode, false otherwise
|
|
*/
|
|
[[nodiscard]] bool
|
|
isFallback() const override;
|
|
|
|
/** @copydoc WriterStateInterface::isFallbackRecovery */
|
|
[[nodiscard]] bool
|
|
isFallbackRecovery() const override;
|
|
|
|
/** @copydoc WriterStateInterface::setFallbackRecovery */
|
|
void
|
|
setFallbackRecovery(bool newValue) override;
|
|
|
|
/** @copydoc WriterStateInterface::isEtlStarted */
|
|
[[nodiscard]] bool
|
|
isEtlStarted() const override;
|
|
|
|
/** @copydoc WriterStateInterface::isCacheFull */
|
|
[[nodiscard]] bool
|
|
isCacheFull() const override;
|
|
|
|
/**
|
|
* @brief Create a clone of this writer state.
|
|
*
|
|
* Creates a new WriterState instance sharing the same system state.
|
|
*
|
|
* @return A unique pointer to the cloned writer state.
|
|
*/
|
|
[[nodiscard]] std::unique_ptr<WriterStateInterface>
|
|
clone() const override;
|
|
};
|
|
|
|
} // namespace etl
|