Add configuration from toml file

This commit is contained in:
2025-08-14 10:59:10 -04:00
parent 2106a336aa
commit a2eef4ce25
6 changed files with 292 additions and 3 deletions

97
src/config.cpp Normal file
View File

@@ -0,0 +1,97 @@
#include "config.hpp"
#include <fstream>
#include <iostream>
#include <toml.hpp>
namespace weaseldb {
std::optional<Config>
ConfigParser::load_from_file(const std::string &file_path) {
try {
const auto toml_data = toml::parse(file_path);
Config config;
parse_server_config(toml_data, config.server);
parse_commit_config(toml_data, config.commit);
parse_subscription_config(toml_data, config.subscription);
return config;
} catch (const std::exception &e) {
std::cerr << "Error parsing config file '" << file_path << "': " << e.what()
<< std::endl;
return std::nullopt;
}
}
std::optional<Config>
ConfigParser::parse_toml_string(const std::string &toml_content) {
try {
const auto toml_data = toml::parse_str(toml_content);
Config config;
parse_server_config(toml_data, config.server);
parse_commit_config(toml_data, config.commit);
parse_subscription_config(toml_data, config.subscription);
return config;
} catch (const std::exception &e) {
std::cerr << "Error parsing TOML content: " << e.what() << std::endl;
return std::nullopt;
}
}
void ConfigParser::parse_server_config(const auto &toml_data,
ServerConfig &config) {
if (toml_data.contains("server")) {
const auto &srv = toml_data.at("server");
if (srv.contains("bind_address")) {
config.bind_address = toml::get<std::string>(srv.at("bind_address"));
}
if (srv.contains("port")) {
config.port = toml::get<int>(srv.at("port"));
}
if (srv.contains("max_request_size_bytes")) {
config.max_request_size_bytes =
toml::get<size_t>(srv.at("max_request_size_bytes"));
}
}
}
void ConfigParser::parse_commit_config(const auto &toml_data,
CommitConfig &config) {
if (toml_data.contains("commit")) {
const auto &commit = toml_data.at("commit");
if (commit.contains("min_request_id_length")) {
config.min_request_id_length =
toml::get<size_t>(commit.at("min_request_id_length"));
}
if (commit.contains("request_id_retention_hours")) {
auto hours = toml::get<int>(commit.at("request_id_retention_hours"));
config.request_id_retention_time = std::chrono::hours{hours};
}
if (commit.contains("request_id_retention_versions")) {
config.request_id_retention_versions =
toml::get<size_t>(commit.at("request_id_retention_versions"));
}
}
}
void ConfigParser::parse_subscription_config(const auto &toml_data,
SubscriptionConfig &config) {
if (toml_data.contains("subscription")) {
const auto &sub = toml_data.at("subscription");
if (sub.contains("max_buffer_size_bytes")) {
config.max_buffer_size_bytes =
toml::get<size_t>(sub.at("max_buffer_size_bytes"));
}
if (sub.contains("keepalive_interval_seconds")) {
auto seconds = toml::get<int>(sub.at("keepalive_interval_seconds"));
config.keepalive_interval = std::chrono::seconds{seconds};
}
}
}
} // namespace weaseldb

49
src/config.hpp Normal file
View File

@@ -0,0 +1,49 @@
#pragma once
#include <chrono>
#include <optional>
#include <string>
namespace weaseldb {
struct ServerConfig {
std::string bind_address = "127.0.0.1";
int port = 8080;
size_t max_request_size_bytes =
1024 * 1024; // 1MB default for 413 Content Too Large
};
struct CommitConfig {
size_t min_request_id_length = 20; // Minimum length for request_id entropy
std::chrono::hours request_id_retention_time{
24}; // How long to keep request IDs
size_t request_id_retention_versions =
100000000; // Min versions to retain request IDs
};
struct SubscriptionConfig {
size_t max_buffer_size_bytes =
10 * 1024 * 1024; // 10MB buffer for unconsumed data
std::chrono::seconds keepalive_interval{30}; // Keepalive comment frequency
};
struct Config {
ServerConfig server;
CommitConfig commit;
SubscriptionConfig subscription;
};
class ConfigParser {
public:
static std::optional<Config> load_from_file(const std::string &file_path);
static std::optional<Config>
parse_toml_string(const std::string &toml_content);
private:
static void parse_server_config(const auto &toml_data, ServerConfig &config);
static void parse_commit_config(const auto &toml_data, CommitConfig &config);
static void parse_subscription_config(const auto &toml_data,
SubscriptionConfig &config);
};
} // namespace weaseldb

View File

@@ -1 +1,38 @@
int main(int argc, char *argv[]) {}
#include "config.hpp"
#include <iostream>
int main(int argc, char *argv[]) {
std::string config_file = "config.toml";
if (argc > 1) {
config_file = argv[1];
}
auto config = weaseldb::ConfigParser::load_from_file(config_file);
if (!config) {
std::cerr << "Failed to load config from: " << config_file << std::endl;
std::cerr << "Using default configuration..." << std::endl;
config = weaseldb::Config{};
}
std::cout << "Configuration loaded successfully:" << std::endl;
std::cout << "Server bind address: " << config->server.bind_address
<< std::endl;
std::cout << "Server port: " << config->server.port << std::endl;
std::cout << "Max request size: " << config->server.max_request_size_bytes
<< " bytes" << std::endl;
std::cout << "Min request ID length: " << config->commit.min_request_id_length
<< std::endl;
std::cout << "Request ID retention: "
<< config->commit.request_id_retention_time.count() << " hours"
<< std::endl;
std::cout << "Subscription buffer size: "
<< config->subscription.max_buffer_size_bytes << " bytes"
<< std::endl;
std::cout << "Keepalive interval: "
<< config->subscription.keepalive_interval.count() << " seconds"
<< std::endl;
return 0;
}