channels: drop stale membership caches on join/leave
After channels.leaveChannel, a client that polls channels.getFullChannel kept receiving a projection that still showed it as an active member (left=false) until the per-(viewer,channel) RPC projection cache and the store-level member cache lapsed on their own or the async read-model NOTIFY landed. The client therefore kept an open compose box while every send was already rejected with CHANNEL_PRIVATE - most visible on public forum supergroups, where getFullChannel keeps succeeding via the preview path instead of tearing the chat down. Every other membership-mutating path already busts these caches synchronously; join/leave/invite/request-approval did not. Add: - store: invalidateChannelMembershipCaches (row + member + dialog caches), called post-commit from JoinChannel, LeaveChannel, ImportInvite, InviteToChannel. - rpc: invalidateChannelMembershipProjection (channelFullProjectionCache pair), called from the join/leave/invite/hide-requests handlers for every user whose membership changed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
d55a97f0a5
commit
2419f47236
7 changed files with 116 additions and 0 deletions
|
|
@ -130,6 +130,7 @@ WHERE channel_id = $1 AND user_id = $2`, channelID, userID, member.ReadInboxMaxI
|
|||
return domain.CreateChannelResult{}, fmt.Errorf("commit join channel: %w", err)
|
||||
}
|
||||
committed = true
|
||||
s.invalidateChannelMembershipCaches(channelID, userID)
|
||||
recipients, _ := s.ListActiveChannelMemberIDs(ctx, userID, channelID, 0)
|
||||
return domain.CreateChannelResult{Channel: channel, Members: []domain.ChannelMember{member}, Message: msg, Event: event, Recipients: recipients}, nil
|
||||
}
|
||||
|
|
@ -259,6 +260,11 @@ WHERE id = $1`, channelID, channel.CreatorUserID, adminsDelta); err != nil {
|
|||
return domain.CreateChannelResult{}, fmt.Errorf("commit leave channel: %w", err)
|
||||
}
|
||||
committed = true
|
||||
leftUserIDs := make([]int64, 0, len(members))
|
||||
for _, m := range members {
|
||||
leftUserIDs = append(leftUserIDs, m.UserID)
|
||||
}
|
||||
s.invalidateChannelMembershipCaches(channelID, leftUserIDs...)
|
||||
recipients = append(recipients, userID)
|
||||
return domain.CreateChannelResult{Channel: channel, Members: members, Message: msg, Event: event, Recipients: recipients}, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue