Repository navigation
sdk: avoid duplicate REQ for subscriptions queued while disconnected - #1492
Merged
yukibtc merged 1 commit intoOct 15, 2026
Merged
Conversation
erskingardner
marked this pull request as ready for review
October 14, 2026 08:34
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
3 tasks done
When `subscribe()` is called while disconnected, its REQ stays in the queue. On reconnect, `resubscribe()` adds a second REQ because the subscription still records the previous connection count. Record the next connection count for REQs queued while disconnected. Handle REQs sent through `send_msg()` the same way. Ref nostrdevkit#1479 (comment) Pull-Request: nostrdevkit#1492 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yuki Kishimoto <yukikishimoto@protonmail.com>
yukibtc
force-pushed
the
sdk/dedupe-queued-req-on-reconnect
branch
from
October 15, 2026 11:37
4075a5f to
99ad550
Compare
yukibtc
approved these changes
Oct 15, 2026
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Here is the follow-up from the #1479 discussion, based on
master.Problem. Take a registered subscription. While the relay is disconnected, queue a REQ for it, either with
relay.subscribe(..).with_id(id)or with a CLOSE + REQ sent throughsend_msg. After the reconnect the relay receivesREQ <id>twice. First comes the queued frame, flushed from the outbound channel. Then the reconnect restore inresubscribe()sends it again. A relay that rejects an already-open subscription ID answers the second REQ withCLOSED duplicate:, and the SDK removes the subscription, so a live subscription is lost without any error.Root cause.
subscribed_connectionwas set tostats.success()when the REQ was queued. While disconnected, that is the count of the session that just ended. After the reconnect,success()is one higher, soshould_resubscriberestores the subscription even though the queued REQ is still in the outbound channel and will go out on this same session.should_resubscribealready handled this for the first connection, but not for later reconnects.Fix. Record the session that will actually write the frame. That is the current session when connected and the next one otherwise. Both values are read under the connection-state lock, so they can't straddle a reconnect. The session is recorded when a long-lived subscription is registered and again whenever a REQ for one is queued, which also covers raw
send_msg. The subscription is only updated once the REQ is queued, so a failed send leaves it unchanged. The first-connection special case inshould_resubscribeis no longer needed and has been removed. The public API does not change.Notes to the reviewers
ControlledRelaywith a newrecording_connectiontest helper, which records written frames and can inject relay replies. For both thesubscribeand the CLOSE + REQ cases, they check three things: exactly oneREQ liveon the reconnected session, the subscription is still registered after replies from a relay that rejects duplicate IDs, and it is not marked for restore. Both fail onmasterand pass with this change. A third test checks that a REQ queued before the first connection is still sent once.subscription_restoration_uses_connection_counterand the same-second restoration tests. Auto-closing subscriptions are still never restored.Connectedand the session dies before the sender writes it, the frame goes out on the next session and is restored there too. Closing this would mean tracking frames at write time, which seemed out of scope.Checklist
CHANGELOG.md(if applicable)🤖 Generated with Claude Code