perf: stop per-frame SQLite writes and console spam, make perf.log opt-in
- Explorer: the tip check runs every frame the Explorer tab is open, and it read both tip rows and rewrote them each time (two autocommit WAL writes per frame). A steady tip is now kept in memory and skips SQLite. A new tip writes both rows in one savepoint, so a crash between them can't pair a new height with the old hash. A test checks that 100 steady checks write nothing. - Console: while the daemon was in the Error state the Console tab added its error line on every poll, i.e. every frame, re-laying out the whole buffer each time. It prints once per error now: on entering Error, when the message changes, or after another crash (EmbeddedDaemon::getUnexpectedExitCount(), never reset). setState writes the message before the state, so a reader that sees Error sees that error's message. The stray " ===" suffix is gone. - perf.log: the profiler appended a block every 300 frames on every run and never rotated the file (tens of MB a day for a wallet left open). It is now off unless the app starts with DRAGONX_PERFLOG=1; otherwise its zone hooks are near no-ops. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "console_channel.h"
|
||||
#include "console_command_reference.h" // consoleCommandCategories / liteConsoleCommandCategories
|
||||
#include "console_input_model.h" // BuildConsoleRpcCall
|
||||
#include "console_tab_helpers.h" // ShouldPrintDaemonErrorLine
|
||||
|
||||
#include "../../app.h"
|
||||
#include "../../data/wallet_state.h"
|
||||
@@ -126,7 +127,16 @@ void FullNodeConsoleExecutor::pollLogLines(const ConsoleAddLineFn& add)
|
||||
add("", ConsoleChannel::None);
|
||||
add(TR("console_daemon_stopped"), ConsoleChannel::Info);
|
||||
} else if (cur == DState::Error) {
|
||||
add(std::string(TR("console_daemon_error")) + d->getLastError() + " ===", ConsoleChannel::Error);
|
||||
// Once per error (see ShouldPrintDaemonErrorLine): printing on every poll added a line per
|
||||
// frame and made the console re-lay-out its whole buffer each time.
|
||||
std::string err = d->getLastError();
|
||||
const std::uint64_t exits = d->getUnexpectedExitCount();
|
||||
if (ShouldPrintDaemonErrorLine(prev == static_cast<int>(DState::Error), true, err, last_daemon_error_,
|
||||
exits != last_printed_exit_count_)) {
|
||||
add(std::string(TR("console_daemon_error")) + " " + err, ConsoleChannel::Error);
|
||||
last_daemon_error_ = std::move(err);
|
||||
last_printed_exit_count_ = exits;
|
||||
}
|
||||
}
|
||||
last_daemon_state_ = static_cast<int>(cur);
|
||||
}
|
||||
|
||||
@@ -110,6 +110,8 @@ private:
|
||||
size_t last_daemon_output_size_ = 0;
|
||||
size_t last_xmrig_output_size_ = 0;
|
||||
int last_daemon_state_ = -1; // daemon::EmbeddedDaemon::State as int
|
||||
std::string last_daemon_error_; // error text last printed (main thread only)
|
||||
std::uint64_t last_printed_exit_count_ = 0; // daemon unexpected-exit count at that print
|
||||
bool last_rpc_connected_ = false;
|
||||
std::deque<std::pair<std::string, bool>> results_; // {text, isError}
|
||||
std::mutex results_mutex_;
|
||||
|
||||
@@ -51,6 +51,13 @@ float ClampConsoleWrapWidth(float contentWidth, float paddingX)
|
||||
return std::max(50.0f, contentWidth - paddingX * 2.0f);
|
||||
}
|
||||
|
||||
bool ShouldPrintDaemonErrorLine(bool wasError, bool isError,
|
||||
const std::string& error, const std::string& lastPrinted,
|
||||
bool newUnexpectedExit)
|
||||
{
|
||||
return isError && (!wasError || error != lastPrinted || newUnexpectedExit);
|
||||
}
|
||||
|
||||
bool ConsoleCommandCarriesSecret(const std::string& cmd)
|
||||
{
|
||||
size_t end = 0;
|
||||
|
||||
@@ -16,6 +16,14 @@ float ComputeConsoleOutputHeight(float availableHeight,
|
||||
float minHeightRatio);
|
||||
float ClampConsoleWrapWidth(float contentWidth, float paddingX);
|
||||
|
||||
// The console's daemon-error line prints once per error: on entering the Error state, when the
|
||||
// reason changes while still in it, or when the daemon crashed again meanwhile (the console only polls
|
||||
// while its tab is shown, so it can miss the Running state between two identical crashes). It used to
|
||||
// print on every poll, i.e. every frame, while in Error.
|
||||
bool ShouldPrintDaemonErrorLine(bool wasError, bool isError,
|
||||
const std::string& error, const std::string& lastPrinted,
|
||||
bool newUnexpectedExit = false);
|
||||
|
||||
// True if `cmd`'s first token names a console/RPC command that carries a SECRET on its command line
|
||||
// (passphrase, private/spending/viewing key, mnemonic). Output-secret commands (dumpprivkey,
|
||||
// z_exportkey, z_exportmnemonic) are NOT covered — their secret is in the result, a separate concern.
|
||||
|
||||
Reference in New Issue
Block a user