Skip to content

Correct the cursor reset docs - #2223

Merged
mpretty-cyro merged 1 commit into
session-foundation:devfrom
mpretty-cyro:fix/cursor-reset-docs
Sep 28, 2026
Merged

mpretty-cyro merged 1 commit into
session-foundation:devfrom
mpretty-cyro:fix/cursor-reset-docs

Conversation

@mpretty-cyro

Copy link
Copy Markdown
Collaborator

Follow-up to #2220. Docs only; no behaviour change.

Release review found that the docs on the cursor reset guard overstated the bug and understated what a reset re-fetches:

  • Cursors are per snode. A reset undone by an in-flight poll delayed that snode's history; it didn't lose it. The history still arrived through another snode, and was lost only in a one-snode swarm.
  • A clear by namespace counts as a reset of every swarm. A swarm it didn't clear re-fetches the in-flight poll's messages from its previous cursor, not from the beginning.
  • Only regular messages are deduplicated. Config messages rely on merging being repeatable, and a kick message seen again is stopped only by the key generation check in its handler.
  • Resets and guarded writes must not be made from inside a database transaction. The guard's lock is held across the SQL, so a caller holding the database while it waits for the lock would deadlock against a write waiting for the database.

That generation check is enough because every client rekeys when it adds a member, with or without history: Android (GroupManagerV2Impl.inviteMembersInternal), iOS (MessageSender.addGroupMembers) and Desktop (handleMemberAddedFromUI, SES3299). A member removed and later re-invited is therefore on a newer generation than the kick they fetch again.

Unit suite: 311 tests, 0 failures, against the published libsession AAR, the same as CI.

The reset guard's docs overstated the bug and understated what a reset
re-fetches:

- An undone reset delayed history rather than losing it: cursors are per
  snode, so the history arrived through another snode, and was lost only in
  a one-snode swarm.
- A clear by namespace counts as a reset of every swarm, so a swarm it didn't
  clear re-fetches from its previous cursor, not the beginning.
- Only regular messages are deduplicated. Config messages rely on merging
  being repeatable, and a kick seen again is stopped only by the key
  generation check.
- Resets and guarded writes must not be made from inside a DB transaction,
  since the guard's lock is held across the SQL.

No behaviour change.
@mpretty-cyro
mpretty-cyro merged commit b330a0f into session-foundation:dev Sep 28, 2026
5 checks passed
@mpretty-cyro
mpretty-cyro deleted the fix/cursor-reset-docs branch September 28, 2026 04:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant