Build 55: surface the Nym/relay connection promptly (fix stuck "Connecting…")
The nostr service only refreshed its connected flag inside the select!s sleep(30s) branch, which restarted on every incoming notification — so the flag could lag the real relay state by 30s+ (or, under steady event flow, never update), leaving the UI stuck on "Connecting…" even though a relay handshake over the Nym mixnet completes in ~2s (measured). Set the flag right after the startup connect, and poll it on an independent 2s interval; the 30s heartbeat work (persist last-seen, TTL prune) stays on its own cadence.
This commit is contained in:
+36
-12
@@ -554,10 +554,23 @@ async fn run_service(svc: Arc<NostrService>, wallet: Wallet) {
|
||||
svc.store.set_last_connected_at(unix_time());
|
||||
svc.store.prune_processed();
|
||||
|
||||
// Reflect the connection the moment we reach the loop instead of leaving the
|
||||
// UI on "Connecting…" until the first heartbeat — by now catch-up has run, so
|
||||
// a relay is typically already up.
|
||||
svc.connected
|
||||
.store(relays_connected(&client).await, Ordering::Relaxed);
|
||||
|
||||
let mut notifications = client.notifications();
|
||||
// Re-run TTL pruning periodically, not just at startup: a session that
|
||||
// never restarts would otherwise let the processed-dedup store grow
|
||||
// unbounded under fresh-keypair spam (the 30-day TTL never applied).
|
||||
// Poll connection state on a SHORT, INDEPENDENT interval. This used to live in
|
||||
// the `select!` behind a `sleep(30s)` that restarted on every notification, so
|
||||
// the flag could lag the real relay state by 30s+ (or, under steady event
|
||||
// flow, never update) — that's the "stuck on Connecting…" the mixnet gets
|
||||
// blamed for, even though a relay handshake over Nym takes ~2s. An `interval`
|
||||
// fires on its own schedule regardless of notifications; the heavier heartbeat
|
||||
// work (persisting last-seen, TTL pruning) stays on a ~30s cadence.
|
||||
let mut status_tick = tokio::time::interval(Duration::from_secs(2));
|
||||
status_tick.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
|
||||
let mut last_heartbeat = unix_time();
|
||||
let mut last_prune = unix_time();
|
||||
loop {
|
||||
if svc.shutdown.load(Ordering::SeqCst) || !wallet.is_open() {
|
||||
@@ -576,15 +589,17 @@ async fn run_service(svc: Arc<NostrService>, wallet: Wallet) {
|
||||
Err(tokio::sync::broadcast::error::RecvError::Closed) => break,
|
||||
}
|
||||
}
|
||||
_ = tokio::time::sleep(Duration::from_secs(30)) => {
|
||||
// Heartbeat: persist last seen time, update connection state.
|
||||
svc.store.set_last_connected_at(unix_time());
|
||||
let connected = client.relays().await.values()
|
||||
.any(|r| r.status() == RelayStatus::Connected);
|
||||
svc.connected.store(connected, Ordering::Relaxed);
|
||||
if unix_time() - last_prune >= 3600 {
|
||||
svc.store.prune_processed();
|
||||
last_prune = unix_time();
|
||||
_ = status_tick.tick() => {
|
||||
svc.connected
|
||||
.store(relays_connected(&client).await, Ordering::Relaxed);
|
||||
let now = unix_time();
|
||||
if now - last_heartbeat >= 30 {
|
||||
last_heartbeat = now;
|
||||
svc.store.set_last_connected_at(now);
|
||||
if now - last_prune >= 3600 {
|
||||
svc.store.prune_processed();
|
||||
last_prune = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -597,6 +612,15 @@ async fn run_service(svc: Arc<NostrService>, wallet: Wallet) {
|
||||
client.disconnect().await;
|
||||
}
|
||||
|
||||
/// True when at least one relay has completed its handshake.
|
||||
async fn relays_connected(client: &Client) -> bool {
|
||||
client
|
||||
.relays()
|
||||
.await
|
||||
.values()
|
||||
.any(|r| r.status() == RelayStatus::Connected)
|
||||
}
|
||||
|
||||
/// Publish kind 10050 DM relay list and, for named identities, kind 0 metadata.
|
||||
async fn publish_identity(svc: &Arc<NostrService>, client: &Client) {
|
||||
let relays = svc.relays();
|
||||
|
||||
Reference in New Issue
Block a user