akiomik / akiomik/nostui

A slow relay ack stalls the whole Nostr worker

未關閉
#515 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
bug
主要語言
Rust
星號
71
分支
5
平均合併
4 小時 2 分鐘
30 天內合併 PR
31

描述

Found while reviewing #513. Pre-existing — #513 neither causes nor worsens it — but that PR makes it visible for the first time, and turns it into something a future change could break silently.

## What happens

`run_subscription_loop` awaits `handle_command` inline inside its `select!` arm (`src/infrastructure/subscription/nostr.rs`). `NostrCommand::SendEventBuilder` awaits `client.send_event(&event).await`, which waits for relay `OK` acknowledgements — nostr-sdk's default is 10s, plus another 10s if NIP-42 authentication is involved.

For that whole window the loop is inside the arm, not at the `select!`. So it processes:

- **no relay notifications** — the timeline stops updating,
- **no other commands** — opening a tab, loading more, and unsubscribing all do nothing.

Worse, `NotificationStream` skips broadcast lag, so events arriving while the loop is blocked can be dropped outright rather than delayed.

Scenario: post a note to a relay that accepts the connection but never acks. For the next ten seconds the feed is frozen, `j`/`k` scroll a timeline nothing is being added to, and pressing `t` to open a tab appears to do nothing.

Before #513 the only sign was the freeze itself. #513 now shows `[Sending] …` for the same window, which makes the cause legible — and makes it obvious the app is waiting on something.

## Why it cannot simply be spawned

The obvious fix — `tokio::spawn` the send instead of awaiting it — would break #513's publish reporting. That design matches `EventPublished` reports to submissions **by position**, which is sound only because the worker never has two publishes outstanding. Spawning would let reports arrive out of order and settle outcomes against the wrong publish: `[Posted] `.

So this needs a correlation id on the command and the report before the concurrency can change. There is a comment at the `select!` arm saying so.

## Suggested shape

- Give `NostrCommand::SendEventBuilder` an id, echo it on `EventPublished`, and have `AppState` match on it instead of on queue position. That removes the ordering dependency.
- Then let sends run concurrently with the notification arm — either by spawning them or by moving publishes onto their own task with their own queue.
- Consider whether other long-awaiting commands (`LoadMore`, the initial contact-list fetch) want the same treatment.

## Acceptance

- Posting to an unresponsive relay does not stop the timeline updating.
- Two publishes in flight at once settle against the right submissions.
- No relay notification is dropped because the worker was busy sending.

貢獻指南

開啟貢獻指南

評估

這個 Issue 還沒有評估資料。

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。