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

Initialise: make snapshots instead of prepending state events #310

Closed
wants to merge 22 commits into from

Conversation

DMRobertson
Copy link
Contributor

@DMRobertson DMRobertson commented Sep 21, 2023

Primarily a perf fix for when the proxy re-joins a room, but it's also arguably a correctness fix because we have no idea how these things appear in the timeline.

@DMRobertson
Copy link
Contributor Author

part of #232 #294

@DMRobertson DMRobertson changed the title WIP make snapshots instead of prepending state events Initialise: make snapshots instead of prepending state events Sep 21, 2023
Comment on lines +668 to +678
func (s *stateMap) Ingest(e Event) (replacedNID int64) {
if e.Type == "m.room.member" {
replacedNID = s.Memberships[e.StateKey]
s.Memberships[e.StateKey] = e.NID
} else {
key := [2]string{e.Type, e.StateKey}
replacedNID = s.Other[key]
s.Other[key] = e.NID
}
return
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't actually use the return value here. At some point I was more ambitious and wanted to reuse this machinery in Accumulate... but then I decided that was not really getting us anything and left it for a rainy day.

Comment on lines +680 to +690
func (s *stateMap) NIDs() (membershipNIDs, otherNIDs []int64) {
membershipNIDs = make([]int64, 0, len(s.Memberships))
otherNIDs = make([]int64, 0, len(s.Other))
for _, nid := range s.Memberships {
membershipNIDs = append(membershipNIDs, nid)
}
for _, nid := range s.Other {
otherNIDs = append(otherNIDs, nid)
}
return
}
Copy link
Contributor Author

@DMRobertson DMRobertson Sep 21, 2023

Choose a reason for hiding this comment

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

It feels a little inefficient to convert from []Event to maps and then back to []int64 again if we're only changing the state by one event. But we're optimising for leaving and rejoining large rooms here, with large gappy state blocks. We've seen gappy state blocks of size multiple thousands on the m.org deployment!

// pull stripped events as this may be huge (think Matrix HQ)
events, err := a.eventsTable.SelectStrippedEventsByNIDs(txn, true, append(snapshot.MembershipEvents, snapshot.OtherEvents...))
if err != nil {
return stateMap{}, err
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We only want event NID, type and state key here, so we could use a more specialised query here to fetch less data.

syncResp = alice.SlidingSync(t,
sync3.Request{
Lists: map[string]sync3.RequestList{
"a": {
Ranges: [][2]int64{{0, 20}},
RoomSubscription: sync3.RoomSubscription{
TimelineLimit: 10,
TimelineLimit: 100,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This test does produce a limited sync for the poller. But that poll is for a new device so gets timelimit limit 1 which wasn't satisfactory---I wanted to confirm that we include timeline events after the gap, but not before.

I felt it was easier to write an integration test so I can use the same poller without any logging out and in shenanigans.

// Update the map from (2) with the events in in `state`. (There must be similar logic already in A ccumulate for this?)
// Store the snapshot. Mark the room's current state as being this snapshot.
//
// 5. If the starting snapshot ID was not zero, emit a cache invalidation payload.
Copy link
Contributor Author

@DMRobertson DMRobertson Sep 21, 2023

Choose a reason for hiding this comment

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

I seem to have forgotten to do this... but the room name changes are seen in the tests. Does that mean the cache invalidation payload isn't needed?

Copy link
Member

Choose a reason for hiding this comment

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

Those tests are only testing cache invalidation via redaction, not cache invalidation via joining a room after a long period of no one being in the room. The latter case is what we're trying to catch here.

Copy link
Contributor Author

@DMRobertson DMRobertson Sep 22, 2023

Choose a reason for hiding this comment

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

I don't follow. I specifically mean TestGappyState and TestGappyStateDoesNotAccumulateTheStateBlock, neither of which emit a redaction event.

state/accumulator.go Outdated Show resolved Hide resolved
state/accumulator.go Outdated Show resolved Hide resolved
state/accumulator.go Outdated Show resolved Hide resolved
state/accumulator.go Outdated Show resolved Hide resolved
state/accumulator.go Show resolved Hide resolved
state/accumulator.go Show resolved Hide resolved
state/accumulator.go Show resolved Hide resolved
// Update the map from (2) with the events in in `state`. (There must be similar logic already in A ccumulate for this?)
// Store the snapshot. Mark the room's current state as being this snapshot.
//
// 5. If the starting snapshot ID was not zero, emit a cache invalidation payload.
Copy link
Member

Choose a reason for hiding this comment

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

Those tests are only testing cache invalidation via redaction, not cache invalidation via joining a room after a long period of no one being in the room. The latter case is what we're trying to catch here.

@DMRobertson
Copy link
Contributor Author

I had to rethink a lot of this. -> #329.

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