Skip to content

fix(mobile): stop membership provider re-querying on session changes - #7741

Open
UgaTheDev wants to merge 1 commit into
block:mainfrom
UgaTheDev:fix/7734-membership-requery
Open

UgaTheDev wants to merge 1 commit into
block:mainfrom
UgaTheDev:fix/7734-membership-requery

Conversation

@UgaTheDev

Copy link
Copy Markdown

Problem

communityMembershipProvider issues a fresh POST /query far more often than it needs to, showing up as /query bursts and aborted in-flight requests in the relay access log (#7734).

Mechanism

mobile/lib/shared/community/community_membership_provider.dart:107-113. Two things compound:

  1. The provider is FutureProvider.autoDispose with no keepAlive(), so it is torn down whenever its last consumer (person_invite_section.dart, invite_create_provider.dart, currentCommunityRoleProvider) unmounts, and the next mount re-runs the body and re-queries. This is the half the regression test reproduces on main.
  2. It ref.watches relaySessionProvider.notifier, which makes it a dependent of the session notifier element, so any RelaySessionNotifier.build() re-run (it watches relayConfigProvider, authProvider, ageSignalProvider) rebuilds this provider too. This half is by code reading: on Riverpod 3.1 a raw state = emission does not propagate through .notifier, so the "session state changes" test in this PR passes on main as well; the dependency bites on build() re-runs (auth / config / age-gate changes), which the test fake does not exercise.

The sibling channelMembersProvider (channel_management_provider.dart:512) already avoids both: it ref.reads the notifier and uses ref.listen(relaySessionProvider, ...) to invalidateSelf() only on a transition into connected. This provider never got the same treatment.

Fix

Mirror the sibling's session handling: ref.read instead of ref.watch on the notifier, and an explicit ref.listen that refetches only when the session transitions into connected. For the remount half, ref.keepAlive() rather than the sibling's snapshot cache — simpler, same effect for a single-instance provider. Community switches still invalidate via the existing ref.watch(relayConfigProvider), and the explicit ref.invalidate(communityMembershipProvider) retry paths (invite_create_page.dart, person_invite_section.dart) are unchanged.

Membership is still enforced by the relay (VISION.md: "The relay enforces all access control"), so a snapshot that is stale until the next reconnect or explicit retry has the same staleness window channel members already accept.

Test

mobile/test/shared/community/community_membership_provider_test.dart — new communityMembershipProvider caching group with a counting RelaySessionNotifier fake:

  • no re-query on reconnecting / disconnected transitions (passes on main too, see above)
  • no re-query on consumer remount — fails on main: Expected: <1> Actual: <2>
  • re-query on explicit invalidation and on reconnect — fails on main: Expected: <3> Actual: <2> (the reconnect refetch is new behavior, matching the sibling)

Run locally with the Hermit-pinned Flutter: flutter test 6/6 on this branch; dart format --set-exit-if-changed clean; flutter analyze clean.

Duplicates

None found (is:pr is:open 7734 in:body → 0).

Out of scope, same anti-pattern, worth a follow-up: pulse_provider.dart and forum_provider.dart also ref.watch(relaySessionProvider.notifier).

Fixes #7734

🤖 Generated with Claude Code

https://claude.ai/code/session_01Qnxf2u2kSBxRM1AT7kD8BD

communityMembershipProvider watched relaySessionProvider.notifier and was
autoDispose, so every relay session rebuild (auth/config/age changes) and
every consumer remount re-ran the HTTP /query round-trip. Read the notifier
instead, keep the snapshot alive, and refresh only on explicit invalidation,
community switch, or a completed (re)connect, matching channelMembersProvider.

Fixes block#7734

Signed-off-by: UgaTheDev <kushzingade@honorsocietyofcinematicarts.org>
@UgaTheDev
UgaTheDev requested a review from a team as a code owner September 18, 2026 15:52
@github-actions

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is 8953cbfff58ed768d996677fed3af0e3bac64a20...1825539a37678f78fbdb77c7576461084d2140a7.
A new review must complete for this exact range. When manual authorization
is required, a Block organization member must comment exactly
@buzz-security-review 1825539a37678f78fbdb77c7576461084d2140a7 to authorize a new review.
Any previous review applies only to its recorded range.

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.

communityMembershipProvider re-queries the relay on every session change and remount

1 participant