This repository has been archived by the owner on Nov 25, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 676
Peeking over federation via MSC2444 #1391
Merged
Merged
Changes from all commits
Commits
Show all changes
92 commits
Select commit
Hold shift + click to select a range
b9342d9
a very very WIP first cut of peeking via MSC2753.
ara4n d7bdf71
make PeekingDeviceSet private
ara4n cfa0be5
merge master
ara4n 9b79f9a
add server_name param
ara4n d343b8f
blind stab at adding a `peek` section to /sync
ara4n c4e5f60
make it build
ara4n d1e4d66
make it launch
ara4n f006b37
add peeking to getResponseWithPDUsForCompleteSync
ara4n 6c3a896
cancel any peeks when we join a room
ara4n 7b38d48
spell out how to runoutside of docker if you want speed
ara4n e589984
fix SQL
ara4n 0bb2c2c
remove unnecessary txn for SelectPeeks
ara4n 28219c6
Merge branch 'master' into matthew/peeking
ara4n 86e9736
fix s/join/peek/ cargocult fail
ara4n d0d5f70
Merge branch 'master' into matthew/peeking
ara4n bfecc8e
HACK: Track goroutine IDs to determine when we write by the wrong thread
kegsay 7bf2a27
Track partition offsets and only log unsafe for non-selects
kegsay fcdb90c
Put redactions in the writer goroutine
kegsay 6410b70
Update filters on writer goroutine
kegsay ed4b3a5
Merge branch 'kegan/redact-txn' into matthew/peeking
ara4n 3cebd8d
Merge branch 'kegan/HACK-goid-sqlite-db-is-locked' into matthew/peeking
ara4n 5d7f688
wrap peek storage in goid hack
ara4n 6424117
use exclusive writer, and MarkPeeksAsOld more efficiently
ara4n 85bce11
don't log ascii in binary at sql trace...
ara4n 75b91ac
strip out empty roomd deltas
ara4n b6cc441
re-add txn to SelectPeeks
ara4n f6af656
re-add accidentally deleted field
ara4n 8712ea3
Merge branch 'master' into matthew/peeking
ara4n eda84cd
reject peeks for non-worldreadable rooms
ara4n da3742c
move perform_peek
ara4n 3c5e079
fix package
ara4n 994cc18
correctly refactor perform_peek
ara4n c1f1fcd
WIP of implementing MSC2444
ara4n 4ca2cf4
typo
ara4n 98cf898
Revert "Merge branch 'kegan/HACK-goid-sqlite-db-is-locked' into matth…
ara4n f236e82
Merge branch 'master' into matthew/peeking-over-fed
ara4n baee97b
(almost) make it build
ara4n 4ef6a3c
clean up bad merge
ara4n 65e59a1
support SendEventWithState with optional event
ara4n a5c0521
fix build & lint
ara4n df29509
fix build & lint
ara4n 410ac72
reinstate federated peeks in the roomserver (doh)
ara4n f8bb448
fix sql thinko
ara4n fff1845
todo for authenticating state returned by /peek
ara4n c6a2604
support returning current state from QueryStateAndAuthChain
ara4n 803647b
handle SS /peek
ara4n 0ae0d11
reimplement SS /peek to prod the RS to tell the FS about the peek
ara4n 4e96e62
rename RemotePeeks as OutboundPeeks
ara4n 59e2be7
rename remote_peeks_table as outbound_peeks_table
ara4n 36e32f1
add perform_handle_remote_peek.go
ara4n 0dc422c
flesh out federation doc
ara4n 71732f2
add inbound peeks table and hook it up
ara4n 8f203fe
rename ambiguous RemotePeek as InboundPeek
ara4n 3caae79
rename FSAPI's PerformPeek as PerformOutboundPeek
ara4n a160c07
setup inbound peeks db correctly
ara4n 32f898d
fix api.SendEventWithState with no event
ara4n 41b9b66
Merge branch 'master' into matthew/peeking-over-fed
ara4n 20e2cb4
track latestevent on /peek
ara4n 3202c7e
go fmt
ara4n 0ab4bc9
document the peek send stream race better
ara4n 75c3f2d
merge master
ara4n 2b4353e
fix SendEventWithRewrite not to bail if handed a non-state event
ara4n 927a62a
add fixme
ara4n 1e6e23d
switch SS /peek to use SendEventWithRewrite
ara4n fd90849
fix comment
ara4n ed9e3fc
use reverse topo ordering to find latest extrem
ara4n efd8656
support postgres for federated peeking
ara4n ebeff8d
go fmt
ara4n 4262095
back out bogus go.mod change
ara4n 797085f
Merge branch 'master' into matthew/peeking-over-fed
neilalexander 814c220
Merge branch 'master' into matthew/peeking-over-fed
neilalexander be5a4e6
Fix performOutboundPeekUsingServer
neilalexander 90017d0
Fix getAuthChain -> GetAuthChain
neilalexander 0fd9e96
Merge branch 'master' into matthew/peeking-over-fed
kegsay a2a5c7e
Merge branch 'master' into matthew/peeking-over-fed
neilalexander 3ba3530
Merge branch 'master' into matthew/peeking-over-fed
neilalexander 7fc3852
Fix build issues
neilalexander d25345d
Merge branch 'master' into matthew/peeking-over-fed
neilalexander c2f7c80
Fix build again
neilalexander fe1d2f8
Merge branch 'master' into matthew/peeking-over-fed
neilalexander 45f0fdd
Merge branch 'master' into matthew/peeking-over-fed
neilalexander d47ab1f
Fix getAuthChain -> GetAuthChain
neilalexander 0fe0e23
Don't repeat outbound peeks for the same room ID to the same servers
neilalexander e0a35c0
Fix lint
neilalexander 8508af3
Merge branch 'master' into matthew/peeking-over-fed
neilalexander 3985d03
Merge branch 'master' into matthew/peeking-over-fed
neilalexander f2dec90
Merge branch 'master' into matthew/peeking-over-fed
neilalexander 609743b
Merge branch 'master' into matthew/peeking-over-fed
kegsay c71bf5d
Merge branch 'master' into matthew/peeking-over-fed
kegsay 4491e53
Don't omitempty to appease sytest
kegsay 552f583
Merge branch 'master' into matthew/peeking-over-fed
kegsay dd3c6ff
Merge branch 'master' into matthew/peeking-over-fed
kegsay File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,26 @@ | ||
## Peeking | ||
|
||
Peeking is implemented as per [MSC2753](https://github.com/matrix-org/matrix-doc/pull/2753). | ||
Local peeking is implemented as per [MSC2753](https://github.com/matrix-org/matrix-doc/pull/2753). | ||
|
||
Implementationwise, this means: | ||
* Users call `/peek` and `/unpeek` on the clientapi from a given device. | ||
* The clientapi delegates these via HTTP to the roomserver, which coordinates peeking in general for a given room | ||
* The roomserver writes an NewPeek event into the kafka log headed to the syncserver | ||
* The syncserver tracks the existence of the local peek in its DB, and then starts waking up the peeking devices for the room in question, putting it in the `peek` section of the /sync response. | ||
* The syncserver tracks the existence of the local peek in the syncapi_peeks table in its DB, and then starts waking up the peeking devices for the room in question, putting it in the `peek` section of the /sync response. | ||
|
||
Questions (given this is [my](https://github.com/ara4n) first time hacking on Dendrite): | ||
* The whole clientapi -> roomserver -> syncapi flow to initiate a peek seems very indirect. Is there a reason not to just let syncapi itself host the implementation of `/peek`? | ||
Peeking over federation is implemented as per [MSC2444](https://github.com/matrix-org/matrix-doc/pull/2444). | ||
|
||
In future, peeking over federation will be added as per [MSC2444](https://github.com/matrix-org/matrix-doc/pull/2444). | ||
* The `roomserver` will kick the `federationsender` much as it does for a federated `/join` in order to trigger a federated `/peek` | ||
* The `federationsender` tracks the existence of the remote peek in question | ||
For requests to peek our rooms ("inbound peeks"): | ||
* Remote servers call `/peek` on federationapi | ||
* The federationapi queries the federationsender to check if this is renewing an inbound peek or not. | ||
* If not, it hits the PerformInboundPeek on the roomserver to ask it for the current state of the room. | ||
* The roomserver atomically (in theory) adds a NewInboundPeek to its kafka stream to tell the federationserver to start peeking. | ||
* The federationsender receives the event, tracks the inbound peek in the federationsender_inbound_peeks table, and starts sending events to the peeking server. | ||
* The federationsender evicts stale inbound peeks which haven't been renewed. | ||
|
||
For peeking into other server's rooms ("outbound peeks"): | ||
* The `roomserver` will kick the `federationsender` much as it does for a federated `/join` in order to trigger a federated outbound `/peek` | ||
* The `federationsender` tracks the existence of the outbound peek in in its federationsender_outbound_peeks table. | ||
* The `federationsender` regularly renews the remote peek as long as there are still peeking devices syncing for it. | ||
* TBD: how do we tell if there are no devices currently syncing for a given peeked room? The syncserver needs to tell the roomserver | ||
somehow who then needs to warn the federationsender. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// Copyright 2020 New Vector Ltd | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package routing | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/matrix-org/dendrite/clientapi/jsonerror" | ||
"github.com/matrix-org/dendrite/roomserver/api" | ||
"github.com/matrix-org/dendrite/setup/config" | ||
"github.com/matrix-org/gomatrixserverlib" | ||
"github.com/matrix-org/util" | ||
) | ||
|
||
// Peek implements the SS /peek API, handling inbound peeks | ||
func Peek( | ||
httpReq *http.Request, | ||
request *gomatrixserverlib.FederationRequest, | ||
cfg *config.FederationAPI, | ||
rsAPI api.RoomserverInternalAPI, | ||
roomID, peekID string, | ||
remoteVersions []gomatrixserverlib.RoomVersion, | ||
) util.JSONResponse { | ||
// TODO: check if we're just refreshing an existing peek by querying the federationsender | ||
|
||
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID} | ||
verRes := api.QueryRoomVersionForRoomResponse{} | ||
if err := rsAPI.QueryRoomVersionForRoom(httpReq.Context(), &verReq, &verRes); err != nil { | ||
return util.JSONResponse{ | ||
Code: http.StatusInternalServerError, | ||
JSON: jsonerror.InternalServerError(), | ||
} | ||
} | ||
|
||
// Check that the room that the peeking server is trying to peek is actually | ||
// one of the room versions that they listed in their supported ?ver= in | ||
// the peek URL. | ||
remoteSupportsVersion := false | ||
for _, v := range remoteVersions { | ||
if v == verRes.RoomVersion { | ||
remoteSupportsVersion = true | ||
break | ||
} | ||
} | ||
// If it isn't, stop trying to peek the room. | ||
if !remoteSupportsVersion { | ||
return util.JSONResponse{ | ||
Code: http.StatusBadRequest, | ||
JSON: jsonerror.IncompatibleRoomVersion(verRes.RoomVersion), | ||
} | ||
} | ||
|
||
// TODO: Check history visibility | ||
|
||
// tell the peeking server to renew every hour | ||
renewalInterval := int64(60 * 60 * 1000 * 1000) | ||
|
||
var response api.PerformInboundPeekResponse | ||
err := rsAPI.PerformInboundPeek( | ||
httpReq.Context(), | ||
&api.PerformInboundPeekRequest{ | ||
RoomID: roomID, | ||
PeekID: peekID, | ||
ServerName: request.Origin(), | ||
RenewalInterval: renewalInterval, | ||
}, | ||
&response, | ||
) | ||
if err != nil { | ||
resErr := util.ErrorResponse(err) | ||
return resErr | ||
} | ||
|
||
if !response.RoomExists { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We would've failed earlier as |
||
return util.JSONResponse{Code: http.StatusNotFound, JSON: nil} | ||
} | ||
|
||
respPeek := gomatrixserverlib.RespPeek{ | ||
StateEvents: gomatrixserverlib.UnwrapEventHeaders(response.StateEvents), | ||
AuthEvents: gomatrixserverlib.UnwrapEventHeaders(response.AuthChainEvents), | ||
RoomVersion: response.RoomVersion, | ||
LatestEvent: response.LatestEvent.Unwrap(), | ||
RenewalInterval: renewalInterval, | ||
} | ||
|
||
return util.JSONResponse{ | ||
Code: http.StatusOK, | ||
JSON: respPeek, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,12 @@ type FederationSenderInternalAPI interface { | |
request *PerformJoinRequest, | ||
response *PerformJoinResponse, | ||
) | ||
// Handle an instruction to peek a room on a remote server. | ||
PerformOutboundPeek( | ||
ctx context.Context, | ||
request *PerformOutboundPeekRequest, | ||
response *PerformOutboundPeekResponse, | ||
) error | ||
// Handle an instruction to make_leave & send_leave with a remote server. | ||
PerformLeave( | ||
ctx context.Context, | ||
|
@@ -111,6 +117,16 @@ type PerformJoinResponse struct { | |
LastError *gomatrix.HTTPError | ||
} | ||
|
||
type PerformOutboundPeekRequest struct { | ||
RoomID string `json:"room_id"` | ||
// The sorted list of servers to try. Servers will be tried sequentially, after de-duplication. | ||
ServerNames types.ServerNames `json:"server_names"` | ||
} | ||
|
||
type PerformOutboundPeekResponse struct { | ||
LastError *gomatrix.HTTPError | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we be getting |
||
} | ||
|
||
type PerformLeaveRequest struct { | ||
RoomID string `json:"room_id"` | ||
UserID string `json:"user_id"` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we care? We time out the peek anyway, and really just because there are no devices currently syncing doesn't mean we should stop peeking. Network interruptions are a reasonable reason, we should still be honouring the renewal period.