Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration and environment variable improvements #4613

Merged
merged 13 commits into from
May 13, 2024
35 changes: 2 additions & 33 deletions nano/lib/env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ std::optional<std::string> nano::env::get (std::string_view name)
return std::nullopt;
}

std::optional<bool> nano::env::get_bool (std::string_view name)
template <>
std::optional<bool> nano::env::get (std::string_view name)
clemahieu marked this conversation as resolved.
Show resolved Hide resolved
{
std::vector<std::string> const on_values{ "1", "true", "on" };
std::vector<std::string> const off_values{ "0", "false", "off" };
Expand All @@ -34,36 +35,4 @@ std::optional<bool> nano::env::get_bool (std::string_view name)
throw std::invalid_argument ("Invalid environment boolean value: " + *value);
}
return std::nullopt;
}

std::optional<int> nano::env::get_int (std::string_view name)
{
if (auto value = get (name))
{
try
{
return std::stoi (*value);
}
catch (std::invalid_argument const &)
{
throw std::invalid_argument ("Invalid environment integer value: " + *value);
}
}
return std::nullopt;
}

std::optional<unsigned> nano::env::get_uint (std::string_view name)
{
if (auto value = get (name))
{
try
{
return std::stoul (*value);
}
catch (std::invalid_argument const &)
{
throw std::invalid_argument ("Invalid environment unsigned integer value: " + *value);
}
}
return std::nullopt;
}
41 changes: 31 additions & 10 deletions nano/lib/env.hpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
#pragma once

#include <boost/lexical_cast.hpp>

#include <optional>
#include <string_view>

/*
* Get environment variable as a specific type or none if variable is not present.
*/
namespace nano::env
{
/**
* Get environment variable as a specific type or none if variable is not present.
*/
std::optional<std::string> get (std::string_view name);

// @throws std::invalid_argument if the value is not a valid boolean
std::optional<bool> get_bool (std::string_view name);

// @throws std::invalid_argument if the value is not a valid integer
std::optional<int> get_int (std::string_view name);
/**
* Get environment variable as a specific type or none if variable is not present.
* @throws std::invalid_argument if the value cannot be converted
*/
template <typename T>
std::optional<T> get (std::string_view name)
{
if (auto value = get (name))
{
try
{
return boost::lexical_cast<T> (*value);
}
catch (boost::bad_lexical_cast const &)
{
throw std::invalid_argument ("Invalid environment value: " + *value);
}
}
return std::nullopt;
}

// @throws std::invalid_argument if the value is not a valid integer
std::optional<unsigned> get_uint (std::string_view name);
/**
* Specialization for boolean values.
* @throws std::invalid_argument if the value is not a valid boolean
*/
template <>
std::optional<bool> get (std::string_view name);
}
2 changes: 1 addition & 1 deletion nano/lib/stats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ std::string nano::stat_log_sink::tm_to_string (tm & tm)
nano::stats::stats (nano::logger & logger_a, nano::stats_config config_a) :
config{ std::move (config_a) },
logger{ logger_a },
enable_logging{ nano::env::get_bool ("NANO_LOG_STATS").value_or (false) }
enable_logging{ nano::env::get<bool> ("NANO_LOG_STATS").value_or (false) }
{
}

Expand Down
2 changes: 1 addition & 1 deletion nano/lib/threading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ boost::thread::attributes nano::thread_attributes::get_default ()
unsigned nano::hardware_concurrency ()
{
static auto const concurrency = [] () {
if (auto value = nano::env::get_uint ("NANO_HARDWARE_CONCURRENCY"))
if (auto value = nano::env::get<unsigned> ("NANO_HARDWARE_CONCURRENCY"))
{
std::cerr << "Hardware concurrency overridden by NANO_HARDWARE_CONCURRENCY environment variable: " << *value << std::endl;
return *value;
Expand Down