Page MenuHomePhabricator

D10666.id33253.diff
No OneTemporary

D10666.id33253.diff

diff --git a/src/seeder/main.cpp b/src/seeder/main.cpp
--- a/src/seeder/main.cpp
+++ b/src/seeder/main.cpp
@@ -238,53 +238,51 @@
}
}
-extern "C" void *ThreadDumper(void *) {
- int count = 0;
- do {
- // First 100s, than 200s, 400s, 800s, 1600s, and then 3200s forever
- UninterruptibleSleep(std::chrono::seconds(100 << count));
- if (count < 5) {
- count++;
- }
+extern "C" void *ThreadDumper(void *data) {
+ assert(data);
+ const auto dumpInterval(*(const std::chrono::seconds *)data);
- {
- std::vector<CAddrReport> v = db.GetAll();
- sort(v.begin(), v.end(), StatCompare);
- FILE *f = fsbridge::fopen("dnsseed.dat.new", "w+");
- if (f) {
- {
- CAutoFile cf(f, SER_DISK, CLIENT_VERSION);
- cf << db;
- }
- rename("dnsseed.dat.new", "dnsseed.dat");
+ // First dump should occur no later than 10 seconds. Successive dumps will
+ // occur every dump interval.
+ UninterruptibleSleep(std::min(10s, dumpInterval));
+ do {
+ std::vector<CAddrReport> v = db.GetAll();
+ sort(v.begin(), v.end(), StatCompare);
+ FILE *f = fsbridge::fopen("dnsseed.dat.new", "w+");
+ if (f) {
+ {
+ CAutoFile cf(f, SER_DISK, CLIENT_VERSION);
+ cf << db;
}
- fsbridge::ofstream d{"dnsseed.dump"};
+ rename("dnsseed.dat.new", "dnsseed.dat");
+ }
+ fsbridge::ofstream d{"dnsseed.dump"};
+ tfm::format(d, "# address good "
+ "lastSuccess %%(2h) %%(8h) %%(1d) %%(7d) "
+ "%%(30d) blocks svcs version\n");
+ double stat[5] = {0, 0, 0, 0, 0};
+ for (CAddrReport rep : v) {
tfm::format(
- d, "# address good "
- "lastSuccess %%(2h) %%(8h) %%(1d) %%(7d) "
- "%%(30d) blocks svcs version\n");
- double stat[5] = {0, 0, 0, 0, 0};
- for (CAddrReport rep : v) {
- tfm::format(
- d,
- "%-47s %4d %11" PRId64
- " %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6i %08" PRIx64
- " %5i \"%s\"\n",
- rep.ip.ToString(), (int)rep.fGood, rep.lastSuccess,
- 100.0 * rep.uptime[0], 100.0 * rep.uptime[1],
- 100.0 * rep.uptime[2], 100.0 * rep.uptime[3],
- 100.0 * rep.uptime[4], rep.blocks, rep.services,
- rep.clientVersion, rep.clientSubVersion);
- stat[0] += rep.uptime[0];
- stat[1] += rep.uptime[1];
- stat[2] += rep.uptime[2];
- stat[3] += rep.uptime[3];
- stat[4] += rep.uptime[4];
- }
- fsbridge::ofstream ff{"dnsstats.log", std::ios_base::app};
- tfm::format(ff, "%llu %g %g %g %g %g\n", GetTime(), stat[0],
- stat[1], stat[2], stat[3], stat[4]);
+ d,
+ "%-47s %4d %11" PRId64
+ " %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6.2f%% %6i %08" PRIx64
+ " %5i \"%s\"\n",
+ rep.ip.ToString(), (int)rep.fGood, rep.lastSuccess,
+ 100.0 * rep.uptime[0], 100.0 * rep.uptime[1],
+ 100.0 * rep.uptime[2], 100.0 * rep.uptime[3],
+ 100.0 * rep.uptime[4], rep.blocks, rep.services,
+ rep.clientVersion, rep.clientSubVersion);
+ stat[0] += rep.uptime[0];
+ stat[1] += rep.uptime[1];
+ stat[2] += rep.uptime[2];
+ stat[3] += rep.uptime[3];
+ stat[4] += rep.uptime[4];
}
+ fsbridge::ofstream ff{"dnsstats.log", std::ios_base::app};
+ tfm::format(ff, "%llu %g %g %g %g %g\n", GetTime(), stat[0], stat[1],
+ stat[2], stat[3], stat[4]);
+
+ UninterruptibleSleep(dumpInterval);
} while (1);
return nullptr;
}
@@ -445,7 +443,7 @@
pthread_attr_destroy(&attr_crawler);
tfm::format(std::cout, "done\n");
pthread_create(&threadStats, nullptr, ThreadStats, nullptr);
- pthread_create(&threadDump, nullptr, ThreadDumper, nullptr);
+ pthread_create(&threadDump, nullptr, ThreadDumper, &opts.dumpInterval);
void *res;
pthread_join(threadDump, &res);
return EXIT_SUCCESS;
diff --git a/src/seeder/options.h b/src/seeder/options.h
--- a/src/seeder/options.h
+++ b/src/seeder/options.h
@@ -5,6 +5,7 @@
#ifndef BITCOIN_SEEDER_OPTIONS_H
#define BITCOIN_SEEDER_OPTIONS_H
+#include <chrono>
#include <set>
#include <string>
@@ -14,6 +15,7 @@
static const int CONTINUE_EXECUTION = -1;
+static const int DEFAULT_DUMP_INTERVAL_SECONDS = 60 * 60;
static const int DEFAULT_NUM_THREADS = 96;
static const int DEFAULT_PORT = 53;
static const int DEFAULT_NUM_DNS_THREADS = 4;
@@ -30,6 +32,7 @@
class CDnsSeedOpts {
public:
ArgsManager *argsManager{nullptr};
+ std::chrono::seconds dumpInterval;
int nThreads;
int nPort;
int nDnsThreads;
@@ -45,12 +48,14 @@
std::set<uint64_t> filter_whitelist;
CDnsSeedOpts(ArgsManager *argsMan)
- : argsManager(argsMan), nThreads(DEFAULT_NUM_THREADS),
- nPort(DEFAULT_PORT), nDnsThreads(DEFAULT_NUM_DNS_THREADS),
- fWipeBan(DEFAULT_WIPE_BAN), fWipeIgnore(DEFAULT_WIPE_IGNORE),
- mbox(DEFAULT_EMAIL), ns(DEFAULT_NAMESERVER), host(DEFAULT_HOST),
- tor(DEFAULT_TOR_PROXY), ip_addr(DEFAULT_LISTEN_ADDRESS),
- ipv4_proxy(DEFAULT_IPV4_PROXY), ipv6_proxy(DEFAULT_IPV6_PROXY) {}
+ : argsManager(argsMan),
+ dumpInterval(std::chrono::seconds(DEFAULT_DUMP_INTERVAL_SECONDS)),
+ nThreads(DEFAULT_NUM_THREADS), nPort(DEFAULT_PORT),
+ nDnsThreads(DEFAULT_NUM_DNS_THREADS), fWipeBan(DEFAULT_WIPE_BAN),
+ fWipeIgnore(DEFAULT_WIPE_IGNORE), mbox(DEFAULT_EMAIL),
+ ns(DEFAULT_NAMESERVER), host(DEFAULT_HOST), tor(DEFAULT_TOR_PROXY),
+ ip_addr(DEFAULT_LISTEN_ADDRESS), ipv4_proxy(DEFAULT_IPV4_PROXY),
+ ipv6_proxy(DEFAULT_IPV6_PROXY) {}
int ParseCommandLine(int argc, const char **argv);
diff --git a/src/seeder/options.cpp b/src/seeder/options.cpp
--- a/src/seeder/options.cpp
+++ b/src/seeder/options.cpp
@@ -35,6 +35,15 @@
return EXIT_SUCCESS;
}
+ dumpInterval = std::chrono::seconds(
+ argsManager->GetArg("-dumpinterval", DEFAULT_DUMP_INTERVAL_SECONDS));
+ if (dumpInterval.count() <= 0) {
+ tfm::format(
+ std::cerr,
+ "Error: -dumpinterval argument expects only positive integers\n");
+ return EXIT_FAILURE;
+ }
+
nThreads = argsManager->GetArg("-threads", DEFAULT_NUM_THREADS);
if (nThreads <= 0) {
tfm::format(
@@ -117,6 +126,11 @@
argsManager->AddArg("-mbox=<mbox>",
"E-Mail address reported in SOA records",
ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
+ argsManager->AddArg(
+ "-dumpinterval=<seconds>",
+ strprintf("Number of seconds between each database dump (default: %d)",
+ DEFAULT_DUMP_INTERVAL_SECONDS),
+ ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsManager->AddArg(
"-threads=<threads>",
strprintf("Number of crawlers to run in parallel (default: %d)",
diff --git a/src/seeder/test/options_tests.cpp b/src/seeder/test/options_tests.cpp
--- a/src/seeder/test/options_tests.cpp
+++ b/src/seeder/test/options_tests.cpp
@@ -24,6 +24,8 @@
BOOST_FIXTURE_TEST_CASE(options_defaults_test, ArgsTestingSetup) {
const char *argv[] = {"ignored"};
BOOST_CHECK(opts.ParseCommandLine(1, argv) == seeder::CONTINUE_EXECUTION);
+ BOOST_CHECK(opts.dumpInterval ==
+ std::chrono::seconds(seeder::DEFAULT_DUMP_INTERVAL_SECONDS));
BOOST_CHECK(opts.nPort == seeder::DEFAULT_PORT);
BOOST_CHECK(opts.nThreads == seeder::DEFAULT_NUM_THREADS);
BOOST_CHECK(opts.nDnsThreads == seeder::DEFAULT_NUM_DNS_THREADS);
@@ -41,6 +43,26 @@
BOOST_CHECK(opts.nPort == 5555);
}
+BOOST_FIXTURE_TEST_CASE(options_dumpinterval_test, ArgsTestingSetup) {
+ const std::map<int, int> expectedResults = {
+ {-9999, EXIT_FAILURE},
+ {-1, EXIT_FAILURE},
+ {0, EXIT_FAILURE},
+ {1, seeder::CONTINUE_EXECUTION},
+ {seeder::DEFAULT_DUMP_INTERVAL_SECONDS, seeder::CONTINUE_EXECUTION},
+ {9999, seeder::CONTINUE_EXECUTION}};
+
+ for (const auto entry : expectedResults) {
+ const std::string testArg = "-dumpinterval=" + ToString(entry.first);
+ const char *argv[] = {"ignored", TEST_HOST, TEST_NAMESERVER, TEST_EMAIL,
+ testArg.c_str()};
+ BOOST_CHECK(opts.ParseCommandLine(5, argv) == entry.second);
+ if (entry.second == seeder::CONTINUE_EXECUTION) {
+ BOOST_CHECK(opts.dumpInterval == std::chrono::seconds(entry.first));
+ }
+ }
+}
+
BOOST_FIXTURE_TEST_CASE(options_threads_test, ArgsTestingSetup) {
const std::map<int, int> expectedResults = {
{-9999, EXIT_FAILURE},

File Metadata

Mime Type
text/plain
Expires
Mon, May 12, 01:43 (3 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5762082
Default Alt Text
D10666.id33253.diff (9 KB)

Event Timeline