Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14362730
D10666.id33253.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Subscribers
None
D10666.id33253.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Mon, May 12, 01:43 (20 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5762082
Default Alt Text
D10666.id33253.diff (9 KB)
Attached To
D10666: Make the seeder dump interval settable by commandline argument
Event Timeline
Log In to Comment