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

Marker events as state - MSC2716 #371

Merged
merged 9 commits into from May 24, 2022

Conversation

MadLittleMods
Copy link
Contributor

@MadLittleMods MadLittleMods commented May 12, 2022

Synapse change: matrix-org/synapse#12718

Part of MSC2716

We're testing to make sure historical messages show up for a remote federated homeserver even when the homeserver is missing the part of the timeline where the marker events were sent and it paginates before they occured to see if the history is available. Making sure the homeserver processes all of the markers from the current state instead of just when it sees them in the timeline.

Sending marker events as state now so they are always able to be seen by homeservers (not lost in some timeline gap).

Marker events should be sent with a unique state_key so that they can all resolve in the current state to easily be discovered.

  • If we re-use the same state_key (like ""), then we would have to fetch previous snapshots of state up through time to find all of the marker events. This way we can avoid all of that.
  • Also avoids state resolution conflicts where only one of the marker events win

As a homeserver, when we see new marker state, we know there is new history imported somewhere back in time and should process it to fetch the insertion event where the historical messages are and set it as an insertion extremity. This way we know where to backfill more messages when someone asks for scrollback.

Dev notes

COMPLEMENT_ALWAYS_PRINT_SERVER_LOGS=1 COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh -run TestImportHistoricalMessages/parallel/Federation/Historical_messages_show_up_for_remote_federated_homeserver_even_when_the_homeserver_is_missing_the_part_of_the_timeline_where_the_marker_was_sent_and_it_paginates_before_it_occured
COMPLEMENT_ALWAYS_PRINT_SERVER_LOGS=1 COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh -run TestImportHistoricalMessages/parallel/Federation/Historical_messages_show_up_for_remote_federated_homeserver_even_when_the_homeserver_is_missing_the_part_of_the_timeline_where_multiple_marker_events_were_sent_and_it_paginates_before_they_occured

// Paginate the /messages endpoint until we find all of the expectedEventIds
// (order does not matter). If any event in denyListEventIDs is found, an error
// will be thrown.
func paginateUntilMessageCheckOff(t *testing.T, c *client.CSAPI, roomID string, fromPaginationToken string, expectedEventIDs []string, denyListEventIDs []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.

This function is originally from #214 but saw that we could use it here before that merges

tests/msc2716_test.go Outdated Show resolved Hide resolved
// Marker events should have unique state_key so they all show up in the current state to process.
unique_state_key := getTxnID("marker_state_key")
// We can't use as.SendEventSynced(...) because application services can't use the /sync API.
markerSendRes := as.MustDoFunc(t, "PUT", []string{"_matrix", "client", "r0", "rooms", roomID, "state", markerEvent.Type, unique_state_key}, client.WithJSONBody(t, markerEvent.Content))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sending marker events as state now so they are always able to be seen by homeservers (not lost in some timeline gap).

Marker events should be sent with a unique state_key so that they can all resolve in the current state to easily be discovered.

  • If we re-use the same state_key (like ""), then we would have to fetch previous snapshots of state up through time to find all of the marker events. This way we can avoid all of that.
  • Also avoids state resolution conflicts where only one of the marker events win

Copy link
Member

Choose a reason for hiding this comment

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

From a design/protocol perspective, this feels sub-optimal. What you really wanted was something like MSC2836 which would allow you to walk back up marker events over federation without needing to put things into state, but oh well.

@MadLittleMods MadLittleMods changed the title Draft: Marker events as state Marker events as state - MSC2716 May 19, 2022
@MadLittleMods MadLittleMods marked this pull request as ready for review May 19, 2022 06:36
@MadLittleMods MadLittleMods requested a review from kegsay May 19, 2022 06:36
tests/msc2716_test.go Outdated Show resolved Hide resolved
// Marker events should have unique state_key so they all show up in the current state to process.
unique_state_key := getTxnID("marker_state_key")
// We can't use as.SendEventSynced(...) because application services can't use the /sync API.
markerSendRes := as.MustDoFunc(t, "PUT", []string{"_matrix", "client", "r0", "rooms", roomID, "state", markerEvent.Type, unique_state_key}, client.WithJSONBody(t, markerEvent.Content))
Copy link
Member

Choose a reason for hiding this comment

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

From a design/protocol perspective, this feels sub-optimal. What you really wanted was something like MSC2836 which would allow you to walk back up marker events over federation without needing to put things into state, but oh well.

MadLittleMods added a commit to matrix-org/synapse that referenced this pull request May 24, 2022
Sending marker events as state now so they are always able to be seen by homeservers (not lost in some timeline gap).

Part of [MSC2716](matrix-org/matrix-spec-proposals#2716)

Complement tests: matrix-org/complement#371

As initially discussed at matrix-org/matrix-spec-proposals#2716 (comment) and matrix-org/matrix-spec-proposals#2716 (comment)

When someone joins a room, process all of the marker events we see in the current state. Marker events should be sent with a unique `state_key` so that they can all resolve in the current state to easily be discovered. Marker events as state

 - If we re-use the same `state_key` (like `""`), then we would have to fetch previous snapshots of state up through time to find all of the marker events. This way we can avoid all of that. This PR was originally doing this but then thought of the smarter way to tackle in an [out of band discussion with @erikjohnston](https://docs.google.com/document/d/1JJDuPfcPNX75fprdTWlxlaKjWOdbdJylbpZ03hzo638/edit#bookmark=id.sm92fqyq7vpp).
 - Also avoids state resolution conflicts where only one of the marker events win

As a homeserver, when we see new marker state, we know there is new history imported somewhere back in time and should process it to fetch the insertion event where the historical messages are and set it as an insertion extremity. This way we know where to backfill more messages when someone asks for scrollback.
@MadLittleMods MadLittleMods merged commit 933c9be into main May 24, 2022
@MadLittleMods MadLittleMods deleted the madlittlemods/marker-events-as-state branch May 24, 2022 01:44
@MadLittleMods
Copy link
Contributor Author

Thanks for the review @kegsay 🦢

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.

None yet

2 participants