Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle gappy state blocks in a performant way #329

Closed
wants to merge 62 commits into from

Conversation

DMRobertson
Copy link
Contributor

@DMRobertson DMRobertson commented Oct 4, 2023

#310 was getting out of control. I did an interactive rebase, threw some things away, and wrote some new things. This is the result.

This PR:

  1. Removes the mechanism of prepending state events to the timeline, creating new snapshots instead.
  2. Emits cache invalidation messages when doing so.
  3. Updates the user cache in response to an invalidation payload.

(3) was the hard part. When I looked at the data in the user cache, the important bits to get right after an invalidation were membership-related. Everything else either didn't look like it ought to be affected by an invalidation, or I didn't care enough to reload them (Spaces). This needs proper testing and I haven't got anything which does that yet.

We could maybe land (3) separately, but either way we need (3) before (1) and (2).

This lacks testing. We probably want an integration test to test a bunch of membership transitions in the gap:

  • unjoined -> join
  • unjoined -> invite
  • invite -> join
  • invite -> leave
  • join -> join {displayname change?}
  • join -> leave
  • join -> ban
  • join -> invite (presumably with a leave in the middle)

@DMRobertson DMRobertson changed the title Second attempt to update the u Handle gappy state blocks in a performant way Oct 4, 2023
sync3/handler/handler.go Outdated Show resolved Hide resolved

t.Log("Alice should see the two most recent message in the timeline only. The room name should change too.")
res = v3.mustDoV3RequestWithPos(t, aliceToken, res.Pos, sync3.Request{})
m.MatchResponse(t, res, m.MatchRoomSubscription(roomID,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also check the prev batch token

state/invites_table.go Outdated Show resolved Hide resolved
David Robertson added 3 commits October 17, 2023 18:42
Needs proxy fixes to the prev_batch token handling
even if the initial load returns no rooms. This is an exceedingly rare
situation since most people have accounts with rooms before using the
proxy. But it does help first-time users and naive test authors.
pubsub/v2.go Outdated
@@ -25,6 +25,7 @@ type V2Listener interface {
OnDeviceMessages(p *V2DeviceMessages)
OnExpiredToken(p *V2ExpiredToken)
OnInvalidateRoom(p *V2InvalidateRoom)
OnStateRedaction(p *V2StateRedaction)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulled out to #359

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably want to have a unit test of the new snapshotting logic in Intialise, if I didn't add one already.

state/storage.go Outdated
Comment on lines 377 to 379
joins map[string]Event,
invites map[string][]json.RawMessage,
leaves map[string]json.RawMessage,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May not need the data here---just the user IDs.

Comment on lines +57 to +60
// ForcePrevBatch is nonempty when the proxy doesn't know the timeline event immediately
// prior to this one. Its value is the prevBatch for this event. If set, this token MUST
// be sent to sync3 clients (or else there'll be a gap in their timeline).
ForcePrevBatch string
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: do we still need this? Should it be pulled out to another PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The motivation was:

// Normally live events don't need a prevBatch because they follow up
// from a previous sync response with a prevBatch. BUT after a gappy poll
// where the user has joined a room, the first time they see a timeline event
// for this room is here. So we need to provide them a prevBatch token.
if roomEventUpdate.EventData.ForcePrevBatch != "" {
r.PrevBatch = roomEventUpdate.EventData.ForcePrevBatch
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the scenario here is seeing in a live update that you've joined a room via a gappy poll.

I think this should actually be impossible now, because we'll kill your connection.

Comment on lines -174 to +175
if s.anchorLoadPosition <= 0 {
if s.anchorLoadPosition < 0 {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we do this again?

RoomID: roomA.RoomID,
JSON: newEvent,
}
dispatcher.OnNewEvent(context.Background(), roomA.RoomID, newEventWrapped, 1)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need this change to OnNewEvent?

m.MatchResponse(
t,
syncResp,
m.MatchRoomSubscription(
roomID,
m.MatchRoomName("potato"),
MatchRoomTimelineMostRecent(1, []Event{{ID: latestMessageID}}),
MatchRoomTimelineMostRecent(1, []Event{{ID: lastMsgID}}),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to take another look at this, I have no memory of this place.

DMRobertson pushed a commit that referenced this pull request Nov 2, 2023
DMRobertson pushed a commit that referenced this pull request Nov 2, 2023
@DMRobertson
Copy link
Contributor Author

Superseded by #363.

@DMRobertson DMRobertson closed this Nov 3, 2023
DMRobertson pushed a commit that referenced this pull request Nov 3, 2023
I don't fully remember the details, but may as well pluck this from the
previous PR.
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.

2 participants