Fix node auto-configuration code:

The `node_size` configuration option is used to automatically
configure various parameters (cache sizes, timeouts, etc) for
the server.

A previous commit included changes that caused incorrect values
to be returned which can result in sub-optimal performance that
can manifest as difficulty syncing to the network, or increased
disk I/O and/or memory usage. The problem was introduced with
commit 66fad62e66.

This commit, if merged, fixes the code to ensure that the correct
values are returned and introduces a compile-time check to prevent
this issue from reoccurring.
This commit is contained in:
Nik Bougalis
2019-12-14 16:30:04 -08:00
parent 63503ee8f0
commit 4bb951d48e
6 changed files with 123 additions and 88 deletions

View File

@@ -32,12 +32,61 @@
#include <boost/format.hpp>
#include <boost/regex.hpp>
#include <boost/system/error_code.hpp>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
namespace ripple {
inline constexpr
std::array<std::pair<SizedItem, std::array<int, 5>>, 11>
sizedItems
{{
// FIXME: We should document each of these items, explaining exactly what
// they control and whether there exists an explicit config option
// that can be used to override the default.
{ SizedItem::sweepInterval,
{{ 10, 30, 60, 90, 120 }} },
{ SizedItem::treeCacheSize,
{{ 128000, 256000, 512000, 768000, 2048000 }} },
{ SizedItem::treeCacheAge,
{{ 30, 60, 90, 120, 900 }} },
{ SizedItem::ledgerSize,
{{ 32, 128, 256, 384, 768 }} },
{ SizedItem::ledgerAge,
{{ 30, 90, 180, 240, 900 }} },
{ SizedItem::ledgerFetch,
{{ 2, 3, 4, 5, 8 }} },
{ SizedItem::nodeCacheSize,
{{ 16384, 32768, 131072, 262144, 524288 }} },
{ SizedItem::nodeCacheAge,
{{ 60, 90, 120, 900, 1800 }} },
{ SizedItem::hashNodeDBCache,
{{ 4, 12, 24, 64, 128 }} },
{ SizedItem::txnDBCache,
{{ 4, 12, 24, 64, 128 }} },
{ SizedItem::lgrDBCache,
{{ 4, 8, 16, 32, 128 }} },
}};
// Ensure that the order of entries in the table corresponds to the
// order of entries in the enum:
static_assert([]() constexpr -> bool
{
std::underlying_type_t<SizedItem> idx = 0;
for (auto const& i : sizedItems)
{
if (static_cast<std::underlying_type_t<SizedItem>>(i.first) != idx)
return false;
++idx;
}
return true;
}(), "Mismatch between sized item enum & array indices");
//
// TODO: Check permissions on config file before using it.
//
@@ -329,14 +378,8 @@ void Config::loadFromString (std::string const& fileContents)
else if (boost::iequals(strTemp, "huge"))
NODE_SIZE = 4;
else
{
NODE_SIZE = beast::lexicalCastThrow <int> (strTemp);
if (NODE_SIZE < 0)
NODE_SIZE = 0;
else if (NODE_SIZE > 4)
NODE_SIZE = 4;
}
NODE_SIZE = std::min<std::size_t>(4,
beast::lexicalCastThrow<std::size_t>(strTemp));
}
if (getSingleSection (secConfig, SECTION_SIGNING_SUPPORT, strTemp, j_))
@@ -594,4 +637,13 @@ boost::filesystem::path Config::getDebugLogFile () const
return log_file;
}
int
Config::getValueFor(SizedItem item, boost::optional<std::size_t> node) const
{
auto const index = static_cast<std::underlying_type_t<SizedItem>>(item);
assert(index < sizedItems.size());
assert(!node || *node <= 4);
return sizedItems.at(index).second.at(node.value_or(NODE_SIZE));
}
} // ripple