Merge branch 'master' into neilalexander/federationinput

This commit is contained in:
Neil Alexander 2022-01-07 13:43:25 +00:00
commit acf5d71c21
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
5 changed files with 62 additions and 11 deletions

View file

@ -16,6 +16,7 @@ import (
"context" "context"
"net/http" "net/http"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/util" "github.com/matrix-org/util"
@ -29,15 +30,42 @@ func GetEventAuth(
roomID string, roomID string,
eventID string, eventID string,
) util.JSONResponse { ) util.JSONResponse {
// TODO: Optimisation: we shouldn't be querying all the room state event, resErr := fetchEvent(ctx, rsAPI, eventID)
// that is in state.StateEvents - we just ignore it. if resErr != nil {
state, err := getState(ctx, request, rsAPI, roomID, eventID) return *resErr
}
if event.RoomID() != roomID {
return util.JSONResponse{Code: http.StatusNotFound, JSON: jsonerror.NotFound("event does not belong to this room")}
}
resErr = allowedToSeeEvent(ctx, request.Origin(), rsAPI, eventID)
if resErr != nil {
return *resErr
}
var response api.QueryStateAndAuthChainResponse
err := rsAPI.QueryStateAndAuthChain(
ctx,
&api.QueryStateAndAuthChainRequest{
RoomID: roomID,
PrevEventIDs: []string{eventID},
AuthEventIDs: event.AuthEventIDs(),
OnlyFetchAuthChain: true,
},
&response,
)
if err != nil { if err != nil {
return *err return util.ErrorResponse(err)
}
if !response.RoomExists {
return util.JSONResponse{Code: http.StatusNotFound, JSON: nil}
} }
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: gomatrixserverlib.RespEventAuth{AuthEvents: state.AuthEvents}, JSON: gomatrixserverlib.RespEventAuth{
AuthEvents: gomatrixserverlib.UnwrapEventHeaders(response.AuthChainEvents),
},
} }
} }

View file

@ -226,6 +226,10 @@ type QueryStateAndAuthChainRequest struct {
PrevEventIDs []string `json:"prev_event_ids"` PrevEventIDs []string `json:"prev_event_ids"`
// The list of auth events for the event. Used to calculate the auth chain // The list of auth events for the event. Used to calculate the auth chain
AuthEventIDs []string `json:"auth_event_ids"` AuthEventIDs []string `json:"auth_event_ids"`
// If true, the auth chain events for the auth event IDs given will be fetched only. Prev event IDs are ignored.
// If false, state and auth chain events for the prev event IDs and entire current state will be included.
// TODO: not a great API shape. It serves 2 main uses: false=>response for send_join, true=>response for /event_auth
OnlyFetchAuthChain bool `json:"only_fetch_auth_chain"`
// Should state resolution be ran on the result events? // Should state resolution be ran on the result events?
// TODO: check call sites and remove if we always want to do state res // TODO: check call sites and remove if we always want to do state res
ResolveState bool `json:"resolve_state"` ResolveState bool `json:"resolve_state"`

View file

@ -78,9 +78,6 @@ func NewRoomserverAPI(
}, },
// perform-er structs get initialised when we have a federation sender to use // perform-er structs get initialised when we have a federation sender to use
} }
if err := a.Inputer.Start(); err != nil {
logrus.WithError(err).Panic("failed to start roomserver input API")
}
return a return a
} }
@ -157,6 +154,10 @@ func (r *RoomserverInternalAPI) SetFederationAPI(fsAPI fsAPI.FederationInternalA
r.Forgetter = &perform.Forgetter{ r.Forgetter = &perform.Forgetter{
DB: r.DB, DB: r.DB,
} }
if err := r.Inputer.Start(); err != nil {
logrus.WithError(err).Panic("failed to start roomserver input API")
}
} }
func (r *RoomserverInternalAPI) SetAppserviceAPI(asAPI asAPI.AppServiceQueryAPI) { func (r *RoomserverInternalAPI) SetAppserviceAPI(asAPI asAPI.AppServiceQueryAPI) {

View file

@ -65,14 +65,15 @@ func (r *Inputer) Start() error {
// later, possibly with an error response to the inputter if synchronous. // later, possibly with an error response to the inputter if synchronous.
func(msg *nats.Msg) { func(msg *nats.Msg) {
roomID := msg.Header.Get("room_id") roomID := msg.Header.Get("room_id")
defer roomserverInputBackpressure.With(prometheus.Labels{"room_id": roomID}).Dec()
var inputRoomEvent api.InputRoomEvent var inputRoomEvent api.InputRoomEvent
if err := json.Unmarshal(msg.Data, &inputRoomEvent); err != nil { if err := json.Unmarshal(msg.Data, &inputRoomEvent); err != nil {
_ = msg.Term() _ = msg.Term()
return return
} }
inbox, _ := r.workers.LoadOrStore(roomID, &phony.Inbox{}) inbox, _ := r.workers.LoadOrStore(roomID, &phony.Inbox{})
roomserverInputBackpressure.With(prometheus.Labels{"room_id": roomID}).Inc()
inbox.(*phony.Inbox).Act(nil, func() { inbox.(*phony.Inbox).Act(nil, func() {
defer roomserverInputBackpressure.With(prometheus.Labels{"room_id": roomID}).Dec()
if err := r.processRoomEvent(context.TODO(), &inputRoomEvent); err != nil { if err := r.processRoomEvent(context.TODO(), &inputRoomEvent); err != nil {
sentry.CaptureException(err) sentry.CaptureException(err)
} else { } else {
@ -117,15 +118,17 @@ func (r *Inputer) InputRoomEvents(
if _, err = r.JetStream.PublishMsg(msg); err != nil { if _, err = r.JetStream.PublishMsg(msg); err != nil {
return return
} }
roomserverInputBackpressure.With(prometheus.Labels{"room_id": roomID}).Inc()
} }
} else { } else {
responses := make(chan error, len(request.InputRoomEvents)) responses := make(chan error, len(request.InputRoomEvents))
defer close(responses) defer close(responses)
for _, e := range request.InputRoomEvents { for _, e := range request.InputRoomEvents {
inputRoomEvent := e inputRoomEvent := e
inbox, _ := r.workers.LoadOrStore(inputRoomEvent.Event.RoomID(), &phony.Inbox{}) roomID := inputRoomEvent.Event.RoomID()
inbox, _ := r.workers.LoadOrStore(roomID, &phony.Inbox{})
roomserverInputBackpressure.With(prometheus.Labels{"room_id": roomID}).Inc()
inbox.(*phony.Inbox).Act(nil, func() { inbox.(*phony.Inbox).Act(nil, func() {
defer roomserverInputBackpressure.With(prometheus.Labels{"room_id": roomID}).Dec()
err := r.processRoomEvent(ctx, &inputRoomEvent) err := r.processRoomEvent(ctx, &inputRoomEvent)
if err != nil { if err != nil {
sentry.CaptureException(err) sentry.CaptureException(err)

View file

@ -457,6 +457,21 @@ func (r *Queryer) QueryStateAndAuthChain(
response.RoomExists = true response.RoomExists = true
response.RoomVersion = info.RoomVersion response.RoomVersion = info.RoomVersion
// handle this entirely separately to the other case so we don't have to pull out
// the entire current state of the room
// TODO: this probably means it should be a different query operation...
if request.OnlyFetchAuthChain {
var authEvents []*gomatrixserverlib.Event
authEvents, err = GetAuthChain(ctx, r.DB.EventsFromIDs, request.AuthEventIDs)
if err != nil {
return err
}
for _, event := range authEvents {
response.AuthChainEvents = append(response.AuthChainEvents, event.Headered(info.RoomVersion))
}
return nil
}
var stateEvents []*gomatrixserverlib.Event var stateEvents []*gomatrixserverlib.Event
stateEvents, err = r.loadStateAtEventIDs(ctx, info, request.PrevEventIDs) stateEvents, err = r.loadStateAtEventIDs(ctx, info, request.PrevEventIDs)
if err != nil { if err != nil {