check relays asynchronously

This commit is contained in:
thePR0M3TH3AN
2025-07-12 09:04:48 -04:00
parent 5f2604fa5a
commit 7745155ee8
9 changed files with 63 additions and 11 deletions

View File

@@ -742,6 +742,7 @@ def handle_settings(password_manager: PasswordManager) -> None:
print(colored("Vault locked. Please re-enter your password.", "yellow"))
password_manager.unlock_vault()
password_manager.start_background_sync()
getattr(password_manager, "start_background_relay_check", lambda: None)()
pause()
elif choice == "13":
handle_display_stats(password_manager)
@@ -779,6 +780,7 @@ def display_menu(
display_fn()
pause()
password_manager.start_background_sync()
getattr(password_manager, "start_background_relay_check", lambda: None)()
while True:
fp, parent_fp, child_fp = getattr(
password_manager,
@@ -796,6 +798,7 @@ def display_menu(
password_manager.lock_vault()
password_manager.unlock_vault()
password_manager.start_background_sync()
getattr(password_manager, "start_background_relay_check", lambda: None)()
continue
# Periodically push updates to Nostr
if (
@@ -819,6 +822,7 @@ def display_menu(
password_manager.lock_vault()
password_manager.unlock_vault()
password_manager.start_background_sync()
getattr(password_manager, "start_background_relay_check", lambda: None)()
continue
password_manager.update_activity()
if not choice:

View File

@@ -925,17 +925,6 @@ class PasswordManager:
parent_seed=getattr(self, "parent_seed", None),
)
if hasattr(self.nostr_client, "check_relay_health"):
healthy = self.nostr_client.check_relay_health(MIN_HEALTHY_RELAYS)
if healthy < MIN_HEALTHY_RELAYS:
print(
colored(
f"Only {healthy} relay(s) responded with your latest event."
" Consider adding more relays via Settings.",
"yellow",
)
)
logger.debug("Managers re-initialized for the new fingerprint.")
except Exception as e:
@@ -984,6 +973,35 @@ class PasswordManager:
self._sync_thread = threading.Thread(target=_worker, daemon=True)
self._sync_thread.start()
def start_background_relay_check(self) -> None:
"""Check relay health in a background thread."""
if (
hasattr(self, "_relay_thread")
and self._relay_thread
and self._relay_thread.is_alive()
):
return
def _worker() -> None:
try:
if getattr(self, "nostr_client", None) and hasattr(
self.nostr_client, "check_relay_health"
):
healthy = self.nostr_client.check_relay_health(MIN_HEALTHY_RELAYS)
if healthy < MIN_HEALTHY_RELAYS:
print(
colored(
f"Only {healthy} relay(s) responded with your latest event."
" Consider adding more relays via Settings.",
"yellow",
)
)
except Exception as exc:
logger.warning(f"Relay health check failed: {exc}")
self._relay_thread = threading.Thread(target=_worker, daemon=True)
self._relay_thread.start()
def sync_index_from_nostr_if_missing(self) -> None:
"""Retrieve the password database from Nostr if it doesn't exist locally."""
index_file = self.fingerprint_dir / "seedpass_entries_db.json.enc"

View File

@@ -23,6 +23,7 @@ def test_auto_sync_triggers_post(monkeypatch):
lock_vault=lambda: None,
unlock_vault=lambda: None,
start_background_sync=lambda: None,
start_background_relay_check=lambda: None,
)
called = False

View File

@@ -0,0 +1,23 @@
import time
from types import SimpleNamespace
from pathlib import Path
import sys
sys.path.append(str(Path(__file__).resolve().parents[1]))
from password_manager.manager import PasswordManager
from constants import MIN_HEALTHY_RELAYS
def test_background_relay_check_runs_async(monkeypatch):
pm = PasswordManager.__new__(PasswordManager)
called = {"args": None}
pm.nostr_client = SimpleNamespace(
check_relay_health=lambda min_relays: called.__setitem__("args", min_relays)
or min_relays
)
pm.start_background_relay_check()
time.sleep(0.05)
assert called["args"] == MIN_HEALTHY_RELAYS

View File

@@ -47,6 +47,7 @@ def _make_pm(called, locked=None):
lock_vault=lock,
unlock_vault=unlock,
start_background_sync=lambda: None,
start_background_relay_check=lambda: None,
)
return pm, locked

View File

@@ -35,6 +35,7 @@ def test_inactivity_triggers_lock(monkeypatch):
lock_vault=lock_vault,
unlock_vault=unlock_vault,
start_background_sync=lambda: None,
start_background_relay_check=lambda: None,
)
monkeypatch.setattr(main, "timed_input", lambda *_: "")
@@ -72,6 +73,7 @@ def test_input_timeout_triggers_lock(monkeypatch):
lock_vault=lock_vault,
unlock_vault=unlock_vault,
start_background_sync=lambda: None,
start_background_relay_check=lambda: None,
)
responses = iter([TimeoutError(), ""])

View File

@@ -31,6 +31,7 @@ def _make_pm(calls):
lock_vault=lambda: None,
unlock_vault=lambda: None,
start_background_sync=lambda: None,
start_background_relay_check=lambda: None,
)

View File

@@ -25,6 +25,7 @@ def _make_pm(calls):
lock_vault=lambda: None,
unlock_vault=lambda: None,
start_background_sync=lambda: None,
start_background_relay_check=lambda: None,
)

View File

@@ -24,6 +24,7 @@ def _make_pm(called):
lock_vault=lambda: None,
unlock_vault=lambda: None,
start_background_sync=lambda: None,
start_background_relay_check=lambda: None,
)
return pm