fix(startup): surface a "taking too long" notice when the daemon won't come up
F3: the daemon connect loop retried forever with only an animated spinner when the daemon was reachable-but-never-ready (stuck in RPC warmup / -28, or an external daemon that never finishes init) -- no error, no guidance, no escape. It now stamps connect_stall_since_ the moment the daemon first goes "reachable but not ready" (the warmup branch + applyDaemonInitStatus) and clears it on connect / disconnect / warmup-complete. A pure, unit-testable util::connectHasStalled() helper (new util/connect_stall.h, 45s default from ui.toml [screens.loading].stall-timeout-sec) drives a "Taking longer than expected" notice in renderLoadingOverlay(): a title, a reassuring body with elapsed seconds, and a full-node hint to Settings > Restart Daemon or the Console. The background retry keeps running underneath, so the notice self-clears the instant it connects. Guarded off while the daemon is in State::Error (that case is owned by the existing crash-count hint). The overlay is a pure draw-list layer with no interactive widgets, so this follows the existing crash-hint idiom (guidance text, not injected buttons); the stalled state is computed locally in the overlay, so the only new App member is connect_stall_since_. Adds testConnectHasStalled to test_phase4.cpp and three i18n keys to i18n.cpp (English source of truth; the res/lang/*.json back-fill is deferred to a single add_missing_translations.py run at the end of the batch). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "chat/chat_database.h"
|
||||
#include "daemon/daemon_controller.h"
|
||||
#include "daemon/embedded_daemon.h"
|
||||
#include "util/connect_stall.h"
|
||||
#include "data/transaction_history_cache.h"
|
||||
#include "data/address_book.h"
|
||||
#include "data/wallet_index.h"
|
||||
@@ -2478,6 +2479,18 @@ void testDaemonShutdownPolicy()
|
||||
EXPECT_TRUE(bootstrap.disconnectRpc);
|
||||
}
|
||||
|
||||
void testConnectHasStalled()
|
||||
{
|
||||
using dragonx::util::connectHasStalled;
|
||||
EXPECT_TRUE(connectHasStalled(100.0, 145.0, 45.0f)); // exactly at threshold
|
||||
EXPECT_TRUE(connectHasStalled(100.0, 300.0, 45.0f)); // well over
|
||||
EXPECT_TRUE(!connectHasStalled(100.0, 144.0, 45.0f)); // just under
|
||||
EXPECT_TRUE(!connectHasStalled(0.0, 1000.0, 45.0f)); // sentinel: not stalling
|
||||
EXPECT_TRUE(!connectHasStalled(-1.0, 1000.0, 45.0f)); // sentinel: not stalling
|
||||
EXPECT_TRUE(!connectHasStalled(10.0, 20.0, 0.0f)); // disabled: threshold 0
|
||||
EXPECT_TRUE(!connectHasStalled(10.0, 20.0, -5.0f)); // disabled: negative threshold
|
||||
}
|
||||
|
||||
void testVerifySaplingParams()
|
||||
{
|
||||
using dragonx::rpc::Connection;
|
||||
@@ -6744,6 +6757,7 @@ int main()
|
||||
testDatadirLockGate();
|
||||
testPlatformEnsureDirectory();
|
||||
testVerifySaplingParams();
|
||||
testConnectHasStalled();
|
||||
testDaemonLifecycleExecution();
|
||||
testDaemonLifecycleAdapters();
|
||||
testConsoleTextLayout();
|
||||
|
||||
Reference in New Issue
Block a user