mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-03 11:22:25 +00:00
fix(nostr): circuit-break the dead nip-07 signer channel
Real-env console (2026-06-15) showed that once the extension's message
port drops under the post-login burst ("message channel closed"), EVERY
subsequent decrypt call hangs to its full ~15s timeout. Each list service
(blocks, hashtags, subscriptions, watch history) independently retries on
that timeout, so the app sits in a permanent loop of 15s-blocking
extension calls — pinning the CPU ("fans at max") and never recovering
until a manual page refresh.
Add a shared circuit breaker at the runNip07WithRetry chokepoint:
- After CIRCUIT_TIMEOUT_THRESHOLD (3) consecutive timeouts the circuit
OPENS; further calls fail fast with code "nip07-channel-unresponsive"
(no multi-second hang), so the retry loops become cheap and the CPU
settles.
- While open, a single probe per CIRCUIT_PROBE_INTERVAL_MS is allowed
through; one success CLOSES the circuit and normal decryption resumes —
no page refresh required.
- Responsive failures (extension answered with an error) reset the
timeout streak — only genuine channel hangs open the circuit.
- Interactive permission prompts bypass the breaker entirely: a user
taking their time at the extension UI can neither trip it nor be
blocked by it, and such a prompt can itself heal the channel.
Increment 2 of the "cut the login burst, then add a safety net" work for
KNOWN_BUGS #0. Test: tests/nostr/nip07-channel-breaker.test.mjs
(cheat-resistant — drives the real queue with hanging/responsive/success
ops; asserts open-after-threshold, fast-fail, probe-recovery, responsive
errors don't open, and bypass is never fast-failed). Full unit suite green.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
71cd04b215
commit
ab57f8d596
4 files changed
+330
-10
No files matched your search
+22
-2
@@ -42,8 +42,28 @@ refactor work in that doc — these are defects.
|
||||
harnesses stay isolated. Regression coverage: `tests/relay-subscribe-cap.test.mjs`
|
||||
(bounded + reserved-defaults + writes-uncapped), and the spec-corrected
|
||||
`user-blocks`, `subscriptions-manager`, and `nostr/client` fetch tests.
|
||||
- **Still deferred:** liveness-ranked health (see #4) and DM decrypt resilience
|
||||
(don't hard-fail DMs on a transient permission miss — retry).
|
||||
- **Real-env follow-up (2026-06-15 console):** the relay cap WORKED (every sub
|
||||
now fans out to exactly 8 relays) but exposed the true blocker: under the
|
||||
post-login burst the nip-07 extension's message port drops ("message channel
|
||||
closed"), after which EVERY decrypt hangs to its ~15s timeout, each list
|
||||
service retries forever, and the app never recovers without a page refresh
|
||||
(CPU pinned — "fans at max"). The signer-readiness gate also took ~67s.
|
||||
Two-part fix in progress ("cut the burst, then add a safety net"):
|
||||
- **Burst reduction (SHIPPED, increment 1):** stop eagerly loading DM history
|
||||
at login (`authSessionCoordinator` `dmStatePromise` now defers; DMs load
|
||||
lazily when the Messages tab opens). Removes a 50-message decrypt burst that
|
||||
competed for the channel. Test: `tests/app/login-defers-dms.test.mjs`.
|
||||
- **Channel circuit breaker (SHIPPED, increment 2):** `js/nostr/nip07Permissions.js`
|
||||
now opens a circuit after `CIRCUIT_TIMEOUT_THRESHOLD` consecutive call
|
||||
timeouts — subsequent calls fail FAST (`code: "nip07-channel-unresponsive"`)
|
||||
instead of each hanging ~15s, so the per-list retry loops stop pinning the
|
||||
CPU. A single periodic probe detects recovery; one success closes the
|
||||
circuit (no refresh). Responsive errors don't open it; interactive permission
|
||||
prompts bypass it. Test: `tests/nostr/nip07-channel-breaker.test.mjs`.
|
||||
- **Still open:** further burst reduction (collapse each list's multi-variant
|
||||
fan-out into one multi-filter REQ per relay; investigate the ~67s signer gate);
|
||||
liveness-ranked relay health (see #4); DM decrypt resilience (don't hard-fail
|
||||
DMs on a transient permission miss — retry).
|
||||
|
||||
### 1. Logged-out: video grid stays empty until a manual refresh
|
||||
- **Severity:** medium (first-load UX, logged-out).
|
||||
|
||||
Reference in new issue
Block a user