mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-06 17:27:58 +00:00
docs: Verify/review config descriptions (#1960)
- Reviewed and modified descriptions. - Added some minor formatting. - Removed the "Key:" before every key name, seems redundant.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,8 @@ Clio needs access to a `rippled` server in order to work. The following configur
|
||||
|
||||
- A port to handle gRPC requests, with the IP(s) of Clio specified in the `secure_gateway` entry
|
||||
|
||||
The example configs of [rippled](https://github.com/XRPLF/rippled/blob/develop/cfg/rippled-example.cfg) and [Clio](../docs/examples/config/example-config.json) are set up in a way that minimal changes are required.
|
||||
The example configs of [rippled](https://github.com/XRPLF/rippled/blob/develop/cfg/rippled-example.cfg) and [Clio](../docs/examples/config/example-config.json) are set up in a way that minimal changes are required. However, if you want to view all configuration keys available in Clio, see [config-description.md](./config-description.md).
|
||||
|
||||
When running locally, the only change needed is to uncomment the `port_grpc` section of the `rippled` config.
|
||||
|
||||
If you're running Clio and `rippled` on separate machines, in addition to uncommenting the `port_grpc` section, a few other steps must be taken:
|
||||
|
||||
@@ -185,7 +185,7 @@ ETLService::publishNextSequence(uint32_t nextSequence)
|
||||
if (!success) {
|
||||
LOG(log_.warn()) << "Failed to publish ledger with sequence = " << nextSequence << " . Beginning ETL";
|
||||
|
||||
// returns the most recent sequence published empty optional if no sequence was published
|
||||
// returns the most recent sequence published. empty optional if no sequence was published
|
||||
std::optional<uint32_t> lastPublished = runETLPipeline(nextSequence, extractorThreads_);
|
||||
LOG(log_.info()) << "Aborting ETL. Falling back to publishing";
|
||||
|
||||
@@ -283,7 +283,6 @@ ETLService::ETLService(
|
||||
finishSequence_ = config.maybeValue<uint32_t>("finish_sequence");
|
||||
state_.isReadOnly = config.get<bool>("read_only");
|
||||
extractorThreads_ = config.get<uint32_t>("extractor_threads");
|
||||
txnThreshold_ = config.get<std::size_t>("txn_threshold");
|
||||
|
||||
// This should probably be done in the backend factory but we don't have state available until here
|
||||
backend_->setCorruptionDetector(CorruptionDetector{state_, backend->cache()});
|
||||
|
||||
@@ -117,7 +117,6 @@ class ETLService : public etlng::ETLServiceInterface, ETLServiceTag {
|
||||
size_t numMarkers_ = 2;
|
||||
std::optional<uint32_t> startSequence_;
|
||||
std::optional<uint32_t> finishSequence_;
|
||||
size_t txnThreshold_ = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -208,7 +208,7 @@ private:
|
||||
void
|
||||
print(std::ostream& stream) const override
|
||||
{
|
||||
stream << fmt::format("The minimum value is `{}`. The maximum value is `{}", kPORT_MIN, kPORT_MAX);
|
||||
stream << fmt::format("The minimum value is `{}`. The maximum value is `{}`.", kPORT_MIN, kPORT_MAX);
|
||||
}
|
||||
|
||||
static constexpr uint32_t kPORT_MIN = 1;
|
||||
@@ -249,7 +249,7 @@ private:
|
||||
void
|
||||
print(std::ostream& stream) const override
|
||||
{
|
||||
stream << "The value must be a valid IP address";
|
||||
stream << "The value must be a valid IP address.";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -313,7 +313,13 @@ private:
|
||||
void
|
||||
print(std::ostream& stream) const override
|
||||
{
|
||||
stream << fmt::format("The value must be one of the following: `{}`", fmt::join(arr_, ", "));
|
||||
std::string valuesStream;
|
||||
std::ranges::for_each(arr_, [&valuesStream](std::string const& elem) {
|
||||
valuesStream += fmt::format(" `{}`,", elem);
|
||||
});
|
||||
// replace the last "," with "."
|
||||
valuesStream.back() = '.';
|
||||
stream << fmt::format("The value must be one of the following:{}", valuesStream);
|
||||
}
|
||||
|
||||
std::string_view key_;
|
||||
@@ -376,7 +382,7 @@ private:
|
||||
void
|
||||
print(std::ostream& stream) const override
|
||||
{
|
||||
stream << fmt::format("The minimum value is `{}`. The maximum value is `{}`", min_, max_);
|
||||
stream << fmt::format("The minimum value is `{}`. The maximum value is `{}`.", min_, max_);
|
||||
}
|
||||
|
||||
NumType min_;
|
||||
@@ -417,7 +423,7 @@ private:
|
||||
void
|
||||
print(std::ostream& stream) const override
|
||||
{
|
||||
stream << fmt::format("The value must be a positive double number");
|
||||
stream << "The value must be a positive double number.";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -433,21 +439,15 @@ static constinit OneOf gValidateProcessingPolicy{"server.processing_policy", kPR
|
||||
|
||||
static constinit PositiveDouble gValidatePositiveDouble{};
|
||||
|
||||
static constinit NumberValueConstraint<uint32_t> gValidateNumMarkers{1, 256};
|
||||
static constinit NumberValueConstraint<uint32_t> gValidateIOThreads{1, std::numeric_limits<uint16_t>::max()};
|
||||
static constinit NumberValueConstraint<uint16_t> gValidateNumMarkers{1, 256};
|
||||
static constinit NumberValueConstraint<uint16_t> gValidateNumCursors{0, std::numeric_limits<uint16_t>::max()};
|
||||
|
||||
static constinit NumberValueConstraint<uint16_t> gValidateUint16{
|
||||
std::numeric_limits<uint16_t>::min(),
|
||||
std::numeric_limits<uint16_t>::max()
|
||||
};
|
||||
// replication factor can be 0
|
||||
static constinit NumberValueConstraint<uint16_t> gValidateReplicationFactor{0, std::numeric_limits<uint16_t>::max()};
|
||||
|
||||
// log file size minimum is 1mb, log rotation time minimum is 1hr
|
||||
static constinit NumberValueConstraint<uint32_t> gValidateLogSize{1, std::numeric_limits<uint32_t>::max()};
|
||||
static constinit NumberValueConstraint<uint32_t> gValidateLogRotationTime{1, std::numeric_limits<uint32_t>::max()};
|
||||
static constinit NumberValueConstraint<uint32_t> gValidateUint32{
|
||||
std::numeric_limits<uint32_t>::min(),
|
||||
std::numeric_limits<uint32_t>::max()
|
||||
};
|
||||
static constinit NumberValueConstraint<uint16_t> gValidateUint16{1, std::numeric_limits<uint16_t>::max()};
|
||||
|
||||
static constinit NumberValueConstraint<uint32_t> gValidateUint32{1, std::numeric_limits<uint32_t>::max()};
|
||||
static constinit NumberValueConstraint<uint32_t> gValidateApiVersion{rpc::kAPI_VERSION_MIN, rpc::kAPI_VERSION_MAX};
|
||||
|
||||
} // namespace util::config
|
||||
|
||||
@@ -266,7 +266,7 @@ static ClioConfigDefinition gClioConfig = ClioConfigDefinition{
|
||||
{"database.cassandra.port", ConfigValue{ConfigType::Integer}.withConstraint(gValidatePort).optional()},
|
||||
{"database.cassandra.keyspace", ConfigValue{ConfigType::String}.defaultValue("clio")},
|
||||
{"database.cassandra.replication_factor",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(3u).withConstraint(gValidateUint16)},
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(3u).withConstraint(gValidateReplicationFactor)},
|
||||
{"database.cassandra.table_prefix", ConfigValue{ConfigType::String}.optional()},
|
||||
{"database.cassandra.max_write_requests_outstanding",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(10'000).withConstraint(gValidateUint32)},
|
||||
@@ -321,7 +321,7 @@ static ClioConfigDefinition gClioConfig = ClioConfigDefinition{
|
||||
.withConstraint(gValidateUint32)},
|
||||
{"server.ip", ConfigValue{ConfigType::String}.withConstraint(gValidateIp)},
|
||||
{"server.port", ConfigValue{ConfigType::Integer}.withConstraint(gValidatePort)},
|
||||
{"server.max_queue_size", ConfigValue{ConfigType::Integer}.defaultValue(0).withConstraint(gValidateUint32)},
|
||||
{"server.max_queue_size", ConfigValue{ConfigType::Integer}.defaultValue(1).withConstraint(gValidateUint32)},
|
||||
{"server.local_admin", ConfigValue{ConfigType::Boolean}.optional()},
|
||||
{"server.admin_password", ConfigValue{ConfigType::String}.optional()},
|
||||
{"server.processing_policy",
|
||||
@@ -334,7 +334,7 @@ static ClioConfigDefinition gClioConfig = ClioConfigDefinition{
|
||||
{"prometheus.enabled", ConfigValue{ConfigType::Boolean}.defaultValue(true)},
|
||||
{"prometheus.compress_reply", ConfigValue{ConfigType::Boolean}.defaultValue(true)},
|
||||
|
||||
{"io_threads", ConfigValue{ConfigType::Integer}.defaultValue(2).withConstraint(gValidateIOThreads)},
|
||||
{"io_threads", ConfigValue{ConfigType::Integer}.defaultValue(2).withConstraint(gValidateUint16)},
|
||||
|
||||
{"subscription_workers", ConfigValue{ConfigType::Integer}.defaultValue(1).withConstraint(gValidateUint32)},
|
||||
|
||||
@@ -342,9 +342,10 @@ static ClioConfigDefinition gClioConfig = ClioConfigDefinition{
|
||||
|
||||
{"cache.num_diffs", ConfigValue{ConfigType::Integer}.defaultValue(32).withConstraint(gValidateUint16)},
|
||||
{"cache.num_markers", ConfigValue{ConfigType::Integer}.defaultValue(48).withConstraint(gValidateUint16)},
|
||||
{"cache.num_cursors_from_diff", ConfigValue{ConfigType::Integer}.defaultValue(0).withConstraint(gValidateUint16)},
|
||||
{"cache.num_cursors_from_account", ConfigValue{ConfigType::Integer}.defaultValue(0).withConstraint(gValidateUint16)
|
||||
},
|
||||
{"cache.num_cursors_from_diff",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(0).withConstraint(gValidateNumCursors)},
|
||||
{"cache.num_cursors_from_account",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(0).withConstraint(gValidateNumCursors)},
|
||||
{"cache.page_fetch_size", ConfigValue{ConfigType::Integer}.defaultValue(512).withConstraint(gValidateUint16)},
|
||||
{"cache.load", ConfigValue{ConfigType::String}.defaultValue("async").withConstraint(gValidateLoadMode)},
|
||||
|
||||
@@ -364,13 +365,12 @@ static ClioConfigDefinition gClioConfig = ClioConfigDefinition{
|
||||
|
||||
{"log_directory", ConfigValue{ConfigType::String}.optional()},
|
||||
|
||||
{"log_rotation_size", ConfigValue{ConfigType::Integer}.defaultValue(2048).withConstraint(gValidateLogSize)},
|
||||
{"log_rotation_size", ConfigValue{ConfigType::Integer}.defaultValue(2048).withConstraint(gValidateUint32)},
|
||||
|
||||
{"log_directory_max_size",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(50 * 1024).withConstraint(gValidateLogSize)},
|
||||
{"log_directory_max_size", ConfigValue{ConfigType::Integer}.defaultValue(50 * 1024).withConstraint(gValidateUint32)
|
||||
},
|
||||
|
||||
{"log_rotation_hour_interval",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(12).withConstraint(gValidateLogRotationTime)},
|
||||
{"log_rotation_hour_interval", ConfigValue{ConfigType::Integer}.defaultValue(12).withConstraint(gValidateUint32)},
|
||||
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("none").withConstraint(gValidateLogTag)},
|
||||
|
||||
@@ -378,8 +378,6 @@ static ClioConfigDefinition gClioConfig = ClioConfigDefinition{
|
||||
|
||||
{"read_only", ConfigValue{ConfigType::Boolean}.defaultValue(false)},
|
||||
|
||||
{"txn_threshold", ConfigValue{ConfigType::Integer}.defaultValue(0).withConstraint(gValidateUint16)},
|
||||
|
||||
{"start_sequence", ConfigValue{ConfigType::Integer}.optional().withConstraint(gValidateUint32)},
|
||||
|
||||
{"finish_sequence", ConfigValue{ConfigType::Integer}.optional().withConstraint(gValidateUint32)},
|
||||
@@ -398,7 +396,6 @@ static ClioConfigDefinition gClioConfig = ClioConfigDefinition{
|
||||
{"migration.full_scan_threads", ConfigValue{ConfigType::Integer}.defaultValue(2).withConstraint(gValidateUint32)},
|
||||
{"migration.full_scan_jobs", ConfigValue{ConfigType::Integer}.defaultValue(4).withConstraint(gValidateUint32)},
|
||||
{"migration.cursors_per_job", ConfigValue{ConfigType::Integer}.defaultValue(100).withConstraint(gValidateUint32)}},
|
||||
|
||||
};
|
||||
|
||||
} // namespace util::config
|
||||
|
||||
@@ -110,12 +110,16 @@ public:
|
||||
static void
|
||||
writeConfigDescriptionToFile(std::ostream& file)
|
||||
{
|
||||
file << "# Clio Config Description\n";
|
||||
file << "This file lists all Clio Configuration definitions in detail.\n\n";
|
||||
file << "## Configuration Details\n\n";
|
||||
file << "# Clio Config Description\n\n";
|
||||
file << "This document provides a list of all available Clio configuration properties in detail.\n\n";
|
||||
file << "> [!NOTE]\n";
|
||||
file << "> Dot notation in configuration key names represents nested fields. For example, "
|
||||
"**database.scylladb** refers to the _scylladb_ field inside the _database_ object. If a key name "
|
||||
"includes \"[]\", it indicates that the nested field is an array (e.g., etl_sources.[]).\n\n";
|
||||
file << "## Configuration Details\n";
|
||||
|
||||
for (auto const& [key, val] : kCONFIG_DESCRIPTION) {
|
||||
file << "### Key: " << key << "\n";
|
||||
file << "\n### " << key << "\n\n";
|
||||
|
||||
// Every type of value is directed to operator<< in ConfigValue.hpp
|
||||
// as ConfigValue is the one that holds all the info regarding the config values
|
||||
@@ -124,137 +128,171 @@ public:
|
||||
} else {
|
||||
file << gClioConfig.getValueView(key);
|
||||
}
|
||||
file << " - **Description**: " << val << "\n";
|
||||
file << "- **Description**: " << val << "\n";
|
||||
}
|
||||
file << "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr auto kCONFIG_DESCRIPTION = std::array{
|
||||
KV{.key = "database.type",
|
||||
.value = "Type of database to use. We currently support Cassandra and Scylladb. We default to Scylladb."},
|
||||
KV{.key = "database.cassandra.contact_points",
|
||||
.value = "A list of IP addresses or hostnames of the initial nodes (Cassandra/Scylladb cluster nodes) that "
|
||||
"the client will connect to when establishing a connection with the database. If you're running "
|
||||
"locally, it should be 'localhost' or 127.0.0.1"},
|
||||
KV{.key = "database.cassandra.secure_connect_bundle",
|
||||
.value = "Configuration file that contains the necessary security credentials and connection details for "
|
||||
"securely "
|
||||
"connecting to a Cassandra database cluster."},
|
||||
KV{.key = "database.cassandra.port", .value = "Port number to connect to the database."},
|
||||
KV{.key = "database.cassandra.keyspace", .value = "Keyspace to use for the database."},
|
||||
KV{.key = "database.cassandra.replication_factor",
|
||||
.value = "Number of replicated nodes for Scylladb. Visit this link for more details : "
|
||||
"https://university.scylladb.com/courses/scylla-essentials-overview/lessons/high-availability/"
|
||||
"topic/fault-tolerance-replication-factor/ "},
|
||||
KV{.key = "database.cassandra.table_prefix", .value = "Prefix for Database table names."},
|
||||
KV{.key = "database.cassandra.max_write_requests_outstanding",
|
||||
.value = "Maximum number of outstanding write requests. Write requests are api calls that write to database "
|
||||
},
|
||||
KV{.key = "database.cassandra.max_read_requests_outstanding",
|
||||
.value = "Maximum number of outstanding read requests, which reads from database"},
|
||||
KV{.key = "database.cassandra.threads", .value = "Number of threads that will be used for database operations."
|
||||
},
|
||||
KV{.key = "database.cassandra.core_connections_per_host",
|
||||
.value = "Number of core connections per host for Cassandra."},
|
||||
KV{.key = "database.cassandra.queue_size_io", .value = "Queue size for I/O operations in Cassandra."},
|
||||
KV{.key = "database.cassandra.write_batch_size", .value = "Batch size for write operations in Cassandra."},
|
||||
KV{.key = "database.cassandra.connect_timeout",
|
||||
.value = "The maximum amount of time in seconds the system will wait for a connection to be successfully "
|
||||
"established "
|
||||
"with the database."},
|
||||
KV{.key = "database.cassandra.request_timeout",
|
||||
.value =
|
||||
"The maximum amount of time in seconds the system will wait for a request to be fetched from database."},
|
||||
"Specifies the type of database used for storing and retrieving data required by the Clio server. Both "
|
||||
"ScyllaDB and Cassandra can serve as backends for Clio; however, this value must be set to `cassandra`."
|
||||
},
|
||||
KV{.key = "database.cassandra.contact_points",
|
||||
.value = "A list of IP addresses or hostnames for the initial cluster nodes (Cassandra or ScyllaDB) that "
|
||||
"the client connects to when establishing a database connection. If you're running Clio locally, "
|
||||
"set this value to `localhost` or `127.0.0.1`."},
|
||||
KV{.key = "database.cassandra.secure_connect_bundle",
|
||||
.value = "The configuration file that contains the necessary credentials and connection details for "
|
||||
"securely connecting to a Cassandra database cluster."},
|
||||
KV{.key = "database.cassandra.port", .value = "The port number used to connect to the Cassandra database."},
|
||||
KV{.key = "database.cassandra.keyspace",
|
||||
.value = "The Cassandra keyspace to use for the database. If you don't provide a value, this is set to "
|
||||
"`clio` by default."},
|
||||
KV{.key = "database.cassandra.replication_factor",
|
||||
.value = "Represents the number of replicated nodes for ScyllaDB. For more details see [Fault Tolerance "
|
||||
"Replication "
|
||||
"Factor](https://university.scylladb.com/courses/scylla-essentials-overview/lessons/"
|
||||
"high-availability/topic/fault-tolerance-replication-factor/)."},
|
||||
KV{.key = "database.cassandra.table_prefix",
|
||||
.value = "An optional field to specify a prefix for the Cassandra database table names."},
|
||||
KV{.key = "database.cassandra.max_write_requests_outstanding",
|
||||
.value = "Represents the maximum number of outstanding write requests. Write requests are API calls that "
|
||||
"write to the database."},
|
||||
KV{.key = "database.cassandra.max_read_requests_outstanding",
|
||||
.value =
|
||||
"Maximum number of outstanding read requests. Read requests are API calls that read from the database."},
|
||||
KV{.key = "database.cassandra.threads",
|
||||
.value = "Represents the number of threads that will be used for database operations."},
|
||||
KV{.key = "database.cassandra.core_connections_per_host",
|
||||
.value = "The number of core connections per host for the Cassandra database."},
|
||||
KV{.key = "database.cassandra.queue_size_io",
|
||||
.value = "Defines the queue size of the input/output (I/O) operations in Cassandra."},
|
||||
KV{.key = "database.cassandra.write_batch_size",
|
||||
.value = "Represents the batch size for write operations in Cassandra."},
|
||||
KV{.key = "database.cassandra.connect_timeout",
|
||||
.value = "The maximum amount of time in seconds that the system waits for a database connection to be "
|
||||
"established."},
|
||||
KV{.key = "database.cassandra.request_timeout",
|
||||
.value = "The maximum amount of time in seconds that the system waits for a request to be fetched from the "
|
||||
"database."},
|
||||
KV{.key = "database.cassandra.username", .value = "The username used for authenticating with the database."},
|
||||
KV{.key = "database.cassandra.password", .value = "The password used for authenticating with the database."},
|
||||
KV{.key = "database.cassandra.certfile",
|
||||
.value = "The path to the SSL/TLS certificate file used to establish a secure connection between the client "
|
||||
"and the "
|
||||
"Cassandra database."},
|
||||
KV{.key = "allow_no_etl", .value = "If True, no ETL nodes will run with Clio."},
|
||||
KV{.key = "etl_sources.[].ip", .value = "IP address of the ETL source."},
|
||||
KV{.key = "etl_sources.[].ws_port", .value = "WebSocket port of the ETL source."},
|
||||
KV{.key = "etl_sources.[].grpc_port", .value = "gRPC port of the ETL source."},
|
||||
"and the Cassandra database."},
|
||||
KV{.key = "allow_no_etl", .value = "If set to `True`, allows Clio to start without any ETL source."},
|
||||
KV{.key = "etl_sources.[].ip", .value = "The IP address of the ETL source."},
|
||||
KV{.key = "etl_sources.[].ws_port", .value = "The WebSocket port of the ETL source."},
|
||||
KV{.key = "etl_sources.[].grpc_port", .value = "The gRPC port of the ETL source."},
|
||||
KV{.key = "forwarding.cache_timeout",
|
||||
.value = "Timeout duration for the forwarding cache used in Rippled communication."},
|
||||
.value = "Specifies the timeout duration (in seconds) for the forwarding cache used in `rippled` "
|
||||
"communication. A value of `0` means disabling this feature."},
|
||||
KV{.key = "forwarding.request_timeout",
|
||||
.value = "Timeout duration for the forwarding request used in Rippled communication."},
|
||||
KV{.key = "rpc.cache_timeout", .value = "Timeout duration for RPC requests."},
|
||||
KV{.key = "num_markers",
|
||||
.value = "The number of markers is the number of coroutines to download the initial ledger"},
|
||||
KV{.key = "dos_guard.whitelist.[]", .value = "List of IP addresses to whitelist for DOS protection."},
|
||||
KV{.key = "dos_guard.max_fetches", .value = "Maximum number of fetch operations allowed by DOS guard."},
|
||||
KV{.key = "dos_guard.max_connections", .value = "Maximum number of concurrent connections allowed by DOS guard."
|
||||
},
|
||||
KV{.key = "dos_guard.max_requests", .value = "Maximum number of requests allowed by DOS guard."},
|
||||
KV{.key = "dos_guard.sweep_interval", .value = "Interval in seconds for DOS guard to sweep/clear its state."},
|
||||
KV{.key = "workers", .value = "Number of threads to process RPC requests."},
|
||||
KV{.key = "server.ip", .value = "IP address of the Clio HTTP server."},
|
||||
KV{.key = "server.port", .value = "Port number of the Clio HTTP server."},
|
||||
KV{.key = "server.max_queue_size",
|
||||
.value = "Maximum size of the server's request queue. Value of 0 is no limit."},
|
||||
KV{.key = "server.local_admin",
|
||||
.value = "Indicates if the server should run with admin privileges. Only one of local_admin or "
|
||||
"admin_password can be set."},
|
||||
KV{.key = "server.admin_password",
|
||||
.value = "Password for Clio admin-only APIs. Only one of local_admin or admin_password can be set."},
|
||||
KV{.key = "server.processing_policy",
|
||||
.value = R"(Could be "sequent" or "parallel". For the sequent policy, requests from a single client
|
||||
connection are processed one by one, with the next request read only after the previous one is processed. For the parallel policy, Clio will accept
|
||||
all requests and process them in parallel, sending a reply for each request as soon as it is ready.)"},
|
||||
KV{.key = "server.parallel_requests_limit",
|
||||
.value =
|
||||
R"(Optional parameter, used only if processing_strategy `parallel`. It limits the number of requests for a single client connection that are processed in parallel. If not specified, the limit is infinite.)"
|
||||
"Specifies the timeout duration (in seconds) for the forwarding request used in `rippled` communication."
|
||||
},
|
||||
KV{.key = "rpc.cache_timeout",
|
||||
.value = "Specifies the timeout duration (in seconds) for RPC cache response to timeout. A value of `0` "
|
||||
"means disabling this feature."},
|
||||
KV{.key = "num_markers", .value = "Specifies the number of coroutines used to download the initial ledger."},
|
||||
KV{.key = "dos_guard.whitelist.[]", .value = "The list of IP addresses to whitelist for DOS protection."},
|
||||
KV{.key = "dos_guard.max_fetches", .value = "The maximum number of fetch operations allowed by DOS guard."},
|
||||
KV{.key = "dos_guard.max_connections",
|
||||
.value = "The maximum number of concurrent connections for a specific IP address."},
|
||||
KV{.key = "dos_guard.max_requests", .value = "The maximum number of requests allowed for a specific IP address."
|
||||
},
|
||||
KV{.key = "dos_guard.sweep_interval", .value = "Interval in seconds for DOS guard to sweep(clear) its state."},
|
||||
KV{.key = "workers", .value = "The number of threads used to process RPC requests."},
|
||||
KV{.key = "server.ip", .value = "The IP address of the Clio HTTP server."},
|
||||
KV{.key = "server.port", .value = "The port number of the Clio HTTP server."},
|
||||
KV{.key = "server.max_queue_size",
|
||||
.value =
|
||||
"The maximum size of the server's request queue. If set to `0`, this means there is no queue size limit."
|
||||
},
|
||||
KV{.key = "server.local_admin",
|
||||
.value = "Indicates if requests from `localhost` are allowed to call Clio admin-only APIs. Note that this "
|
||||
"setting cannot be enabled "
|
||||
"together with [server.admin_password](#serveradmin_password)."},
|
||||
KV{.key = "server.admin_password",
|
||||
.value = "The password for Clio admin-only APIs. Note that this setting cannot be enabled together with "
|
||||
"[server.local_admin](#serveradmin_password)."},
|
||||
KV{.key = "server.processing_policy",
|
||||
.value = "For the `sequent` policy, requests from a single client connection are processed one by one, with "
|
||||
"the next request read only after the previous one is processed. For the `parallel` policy, Clio "
|
||||
"will accept all requests and process them in parallel, sending a reply for each request as soon "
|
||||
"as it is ready."},
|
||||
KV{.key = "server.parallel_requests_limit",
|
||||
.value = "This is an optional parameter, used only if the `processing_strategy` is `parallel`. It limits "
|
||||
"the number of requests processed in parallel for a single client connection. If not specified, no "
|
||||
"limit is enforced."},
|
||||
KV{.key = "server.ws_max_sending_queue_size",
|
||||
.value = "Maximum queue size for sending subscription data to clients. This queue buffers data when a "
|
||||
"client is slow to receive it, ensuring delivery once the client is ready."},
|
||||
KV{.key = "prometheus.enabled", .value = "Enables or disables Prometheus metrics."},
|
||||
KV{.key = "prometheus.compress_reply", .value = "Enables or disables compression of Prometheus responses."},
|
||||
KV{.key = "io_threads", .value = "The number of input/output (I/O) threads. The value cannot be less than `1`."
|
||||
},
|
||||
KV{.key = "server.ws_max_sending_queue_size", .value = "Maximum size of the websocket sending queue."},
|
||||
KV{.key = "prometheus.enabled", .value = "Enable or disable Prometheus metrics."},
|
||||
KV{.key = "prometheus.compress_reply", .value = "Enable or disable compression of Prometheus responses."},
|
||||
KV{.key = "io_threads", .value = "Number of I/O threads. Value cannot be less than 1"},
|
||||
KV{.key = "subscription_workers",
|
||||
.value = "The number of worker threads or processes that are responsible for managing and processing "
|
||||
"subscription-based tasks from rippled"},
|
||||
KV{.key = "graceful_period", .value = "Number of milliseconds server will wait to shutdown gracefully."},
|
||||
KV{.key = "cache.num_diffs", .value = "Number of diffs to cache. For more info, consult readme.md in etc"},
|
||||
KV{.key = "cache.num_markers", .value = "Number of markers to cache."},
|
||||
KV{.key = "cache.num_cursors_from_diff", .value = "Num of cursors that are different."},
|
||||
KV{.key = "cache.num_cursors_from_account", .value = "Number of cursors from an account."},
|
||||
KV{.key = "cache.page_fetch_size", .value = "Page fetch size for cache operations."},
|
||||
KV{.key = "cache.load", .value = "Cache loading strategy ('sync' or 'async')."},
|
||||
KV{.key = "log_channels.[].channel",
|
||||
.value = "Name of the log channel."
|
||||
"'RPC', 'ETL', and 'Performance'"},
|
||||
KV{.key = "log_channels.[].log_level",
|
||||
.value = "Log level for the specific log channel."
|
||||
"`warning`, `error`, `fatal`"},
|
||||
"subscription-based tasks from `rippled`."},
|
||||
KV{.key = "graceful_period",
|
||||
.value = "The number of milliseconds the server waits to shutdown gracefully. If Clio does not shutdown "
|
||||
"gracefully after the specified value, it will be killed instead."},
|
||||
KV{.key = "cache.num_diffs",
|
||||
.value = "The number of cursors generated is the number of changed (without counting deleted) objects in "
|
||||
"the latest `cache.num_diffs` number of ledgers. Cursors are workers that load the ledger cache "
|
||||
"from the position of markers concurrently. For more information, please read "
|
||||
"[README.md](../src/etl/README.md)."},
|
||||
KV{.key = "cache.num_markers",
|
||||
.value = " Specifies how many markers are placed randomly within the cache. These markers define the "
|
||||
"positions on the ledger that will be loaded concurrently by the workers. The higher the number, "
|
||||
"the more places within the cache we potentially cover."},
|
||||
KV{.key = "cache.num_cursors_from_diff",
|
||||
.value = "`cache.num_cursors_from_diff` number of cursors are generated by looking at the number of changed "
|
||||
"objects in the most recent ledger. If number of changed objects in current ledger is not enough, "
|
||||
"it will keep reading previous ledgers until it hit `cache.num_cursors_from_diff`. If set to `0`, "
|
||||
"the system defaults to generating cursors based on `cache.num_diffs`."},
|
||||
KV{.key = "cache.num_cursors_from_account",
|
||||
.value = "`cache.num_cursors_from_diff` of cursors are generated by reading accounts in `account_tx` table. "
|
||||
"If set to `0`, the system defaults to generating cursors based on `cache.num_diffs`."},
|
||||
KV{.key = "cache.page_fetch_size", .value = "The number of ledger objects to fetch concurrently per marker."},
|
||||
KV{.key = "cache.load", .value = "The strategy used for Cache loading."},
|
||||
KV{.key = "log_channels.[].channel", .value = "The name of the log channel."},
|
||||
KV{.key = "log_channels.[].log_level", .value = "The log level for the specific log channel."},
|
||||
KV{.key = "log_level",
|
||||
.value = "General logging level of Clio. This level will be applied to all log channels that do not have an "
|
||||
.value = "The general logging level of Clio. This level is applied to all log channels that do not have an "
|
||||
"explicitly defined logging level."},
|
||||
KV{.key = "log_format", .value = "Format string for log messages."},
|
||||
KV{.key = "log_to_console", .value = "Enable or disable logging to console."},
|
||||
KV{.key = "log_directory", .value = "Directory path for log files."},
|
||||
KV{.key = "log_format",
|
||||
.value = "The format string for log messages. The format is described here: "
|
||||
"https://www.boost.org/doc/libs/1_83_0/libs/log/doc/html/log/tutorial/formatters.html."},
|
||||
KV{.key = "log_to_console", .value = "Enables or disables logging to the console."},
|
||||
KV{.key = "log_directory", .value = "The directory path for the log files."},
|
||||
KV{.key = "log_rotation_size",
|
||||
.value =
|
||||
"Log rotation size in megabytes. When the log file reaches this particular size, a new log file starts."
|
||||
},
|
||||
KV{.key = "log_directory_max_size", .value = "Maximum size of the log directory in megabytes."},
|
||||
.value = "The log rotation size in megabytes. When the log file reaches this particular size, a new log "
|
||||
"file starts."},
|
||||
KV{.key = "log_directory_max_size", .value = "The maximum size of the log directory in megabytes."},
|
||||
KV{.key = "log_rotation_hour_interval",
|
||||
.value = "Interval in hours for log rotation. If the current log file reaches this value in logging, a new "
|
||||
"log file starts."},
|
||||
KV{.key = "log_tag_style", .value = "Style for log tags."},
|
||||
KV{.key = "extractor_threads", .value = "Number of extractor threads."},
|
||||
KV{.key = "read_only", .value = "Indicates if the server should have read-only privileges."},
|
||||
KV{.key = "txn_threshold", .value = "Transaction threshold value."},
|
||||
KV{.key = "start_sequence", .value = "Starting ledger index."},
|
||||
KV{.key = "finish_sequence", .value = "Ending ledger index."},
|
||||
KV{.key = "ssl_cert_file", .value = "Path to the SSL certificate file."},
|
||||
KV{.key = "ssl_key_file", .value = "Path to the SSL key file."},
|
||||
KV{.key = "api_version.default", .value = "Default API version Clio will run on."},
|
||||
KV{.key = "api_version.min", .value = "Minimum API version."},
|
||||
KV{.key = "api_version.max", .value = "Maximum API version."},
|
||||
.value = "Represents the interval (in hours) for log rotation. If the current log file reaches this value "
|
||||
"in logging, a new log file starts."},
|
||||
KV{.key = "log_tag_style",
|
||||
.value =
|
||||
"Log tags are unique identifiers for log messages. `uint`/`int` starts logging from 0 and increments, "
|
||||
"making it faster. In contrast, `uuid` generates a random unique identifier, which adds overhead."},
|
||||
KV{.key = "extractor_threads", .value = "Number of threads used to extract data from ETL source."},
|
||||
KV{.key = "read_only", .value = "Indicates if the server is allowed to write data to the database."},
|
||||
KV{.key = "start_sequence",
|
||||
.value = "If specified, the ledger index Clio will start writing to the database from."},
|
||||
KV{.key = "finish_sequence", .value = "If specified, the final ledger that Clio will write to the database."},
|
||||
KV{.key = "ssl_cert_file", .value = "The path to the SSL certificate file."},
|
||||
KV{.key = "ssl_key_file", .value = "The path to the SSL key file."},
|
||||
KV{.key = "api_version.default", .value = "The default API version that the Clio server will run on."},
|
||||
KV{.key = "api_version.min", .value = "The minimum API version allowed to use."},
|
||||
KV{.key = "api_version.max", .value = "The maximum API version allowed to use."},
|
||||
KV{.key = "migration.full_scan_threads", .value = "The number of threads used to scan the table."},
|
||||
KV{.key = "migration.full_scan_jobs", .value = "The number of coroutines used to scan the table."},
|
||||
KV{.key = "migration.cursors_per_job", .value = "The number of cursors each coroutine will scan."}
|
||||
KV{.key = "migration.cursors_per_job", .value = "The number of cursors each job will scan."}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -217,8 +217,10 @@ public:
|
||||
stream << "- **Type**: " << val.type() << "\n";
|
||||
if (val.description_.has_value()) {
|
||||
stream << "- **Default value**: " << *val.description_ << "\n";
|
||||
} else if (val.hasValue()) {
|
||||
stream << "- **Default value**: `" << *val.value_ << "`\n";
|
||||
} else {
|
||||
stream << "- **Default value**: " << (val.hasValue() ? *val.value_ : "None") << "\n";
|
||||
stream << "- **Default value**: None\n";
|
||||
}
|
||||
stream << "- **Constraints**: ";
|
||||
|
||||
|
||||
@@ -97,13 +97,13 @@ protected:
|
||||
{"log_directory", ConfigValue{ConfigType::String}.optional()},
|
||||
|
||||
{"log_rotation_size",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(2048).withConstraint(config::gValidateLogSize)},
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(2048).withConstraint(config::gValidateUint32)},
|
||||
|
||||
{"log_directory_max_size",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(50 * 1024).withConstraint(config::gValidateLogSize)},
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(50 * 1024).withConstraint(config::gValidateUint32)},
|
||||
|
||||
{"log_rotation_hour_interval",
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(12).withConstraint(config::gValidateLogRotationTime)},
|
||||
ConfigValue{ConfigType::Integer}.defaultValue(12).withConstraint(config::gValidateUint32)},
|
||||
|
||||
{"log_tag_style", ConfigValue{ConfigType::String}.defaultValue("none")},
|
||||
};
|
||||
|
||||
@@ -213,7 +213,10 @@ TEST_F(CliArgsTestsWithTmpFile, Parse_ConfigDescriptionFileContent)
|
||||
|
||||
auto const fileContent = buffer.str();
|
||||
EXPECT_TRUE(fileContent.find("# Clio Config Description") != std::string::npos);
|
||||
EXPECT_TRUE(fileContent.find("This file lists all Clio Configuration definitions in detail.") != std::string::npos);
|
||||
EXPECT_TRUE(
|
||||
fileContent.find("This document provides a list of all available Clio configuration properties in detail.") !=
|
||||
std::string::npos
|
||||
);
|
||||
EXPECT_TRUE(fileContent.find("## Configuration Details") != std::string::npos);
|
||||
|
||||
// all keys that exist in clio config should be listed in config description file
|
||||
|
||||
@@ -173,10 +173,11 @@ TEST(ConfigDescription, GetValues)
|
||||
|
||||
EXPECT_EQ(
|
||||
definition.get("database.type"),
|
||||
"Type of database to use. We currently support Cassandra and Scylladb. We default to Scylladb."
|
||||
"Specifies the type of database used for storing and retrieving data required by the Clio server. Both "
|
||||
"ScyllaDB and Cassandra can serve as backends for Clio; however, this value must be set to `cassandra`."
|
||||
);
|
||||
EXPECT_EQ(definition.get("etl_sources.[].ip"), "IP address of the ETL source.");
|
||||
EXPECT_EQ(definition.get("prometheus.enabled"), "Enable or disable Prometheus metrics.");
|
||||
EXPECT_EQ(definition.get("etl_sources.[].ip"), "The IP address of the ETL source.");
|
||||
EXPECT_EQ(definition.get("prometheus.enabled"), "Enables or disables Prometheus metrics.");
|
||||
}
|
||||
|
||||
struct ConfigDescriptionAssertTest : common::util::WithMockAssert {};
|
||||
|
||||
@@ -236,7 +236,7 @@ TEST_F(ConstraintTest, SetValuesOnNumberConstraint)
|
||||
auto positiveNum = ConfigValue{ConfigType::Integer}.defaultValue(20u).withConstraint(gValidateUint16);
|
||||
auto const err = positiveNum.setValue(-22, "key");
|
||||
EXPECT_TRUE(err.has_value());
|
||||
EXPECT_EQ(err->error, fmt::format("key Number must be between {} and {}", 0, 65535));
|
||||
EXPECT_EQ(err->error, fmt::format("key Number must be between {} and {}", 1, 65535));
|
||||
EXPECT_FALSE(positiveNum.setValue(99, "key"));
|
||||
}
|
||||
|
||||
@@ -268,7 +268,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||
ConstraintTestBundle{"ipConstraint", gValidateIp},
|
||||
ConstraintTestBundle{"channelConstraint", gValidateChannelName},
|
||||
ConstraintTestBundle{"logLevelConstraint", gValidateLogLevelName},
|
||||
ConstraintTestBundle{"cannsandraNameCnstraint", gValidateCassandraName},
|
||||
ConstraintTestBundle{"cassandraNameConstraint", gValidateCassandraName},
|
||||
ConstraintTestBundle{"loadModeConstraint", gValidateLoadMode},
|
||||
ConstraintTestBundle{"ChannelNameConstraint", gValidateChannelName},
|
||||
ConstraintTestBundle{"ApiVersionConstraint", gValidateApiVersion},
|
||||
|
||||
Reference in New Issue
Block a user