mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-10 16:33:11 -06:00
Include the state before the event in roomserver output
This commit is contained in:
parent
c6e59ca967
commit
a7e20d1658
|
|
@ -22,9 +22,6 @@ import (
|
|||
type OutputRoomEvent struct {
|
||||
// The JSON bytes of the event.
|
||||
Event []byte
|
||||
// The state event IDs needed to determine who can see this event.
|
||||
// This can be used to tell which users to send the event to.
|
||||
VisibilityEventIDs []string
|
||||
// The latest events in the room after this event.
|
||||
// This can be used to set the prev events for new events in the room.
|
||||
// This also can be used to get the full current state after this event.
|
||||
|
|
@ -43,6 +40,14 @@ type OutputRoomEvent struct {
|
|||
// If the LastSentEventID doesn't match what they were expecting it to be
|
||||
// they can use the LatestEventIDs to request the full current state.
|
||||
LastSentEventID string
|
||||
// The state event IDs that are part of the state at the event, but not
|
||||
// part of the current state. Together with the StateBeforeRemovesEventIDs
|
||||
// this can be used to construct the state before the event from the
|
||||
// current state.
|
||||
StateBeforeAddsEventIDs []string
|
||||
// The state event IDs that are part of the current state, but not part
|
||||
// of the state at the event.
|
||||
StateBeforeRemovesEventIDs []string
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaller
|
||||
|
|
@ -52,12 +57,14 @@ func (ore *OutputRoomEvent) UnmarshalJSON(data []byte) error {
|
|||
// We use json.RawMessage so that the event JSON is sent as JSON rather than
|
||||
// being base64 encoded which is the default for []byte.
|
||||
var content struct {
|
||||
Event *json.RawMessage
|
||||
VisibilityEventIDs []string
|
||||
LatestEventIDs []string
|
||||
AddsStateEventIDs []string
|
||||
RemovesStateEventIDs []string
|
||||
LastSentEventID string
|
||||
Event *json.RawMessage
|
||||
VisibilityEventIDs []string
|
||||
LatestEventIDs []string
|
||||
AddsStateEventIDs []string
|
||||
RemovesStateEventIDs []string
|
||||
LastSentEventID string
|
||||
StateBeforeAddsEventIDs []string
|
||||
StateBeforeRemovesEventIDs []string
|
||||
}
|
||||
if err := json.Unmarshal(data, &content); err != nil {
|
||||
return err
|
||||
|
|
@ -65,11 +72,12 @@ func (ore *OutputRoomEvent) UnmarshalJSON(data []byte) error {
|
|||
if content.Event != nil {
|
||||
ore.Event = []byte(*content.Event)
|
||||
}
|
||||
ore.VisibilityEventIDs = content.VisibilityEventIDs
|
||||
ore.LatestEventIDs = content.LatestEventIDs
|
||||
ore.AddsStateEventIDs = content.AddsStateEventIDs
|
||||
ore.RemovesStateEventIDs = content.RemovesStateEventIDs
|
||||
ore.LastSentEventID = content.LastSentEventID
|
||||
ore.StateBeforeAddsEventIDs = content.StateBeforeAddsEventIDs
|
||||
ore.StateBeforeRemovesEventIDs = content.StateBeforeRemovesEventIDs
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -81,19 +89,22 @@ func (ore OutputRoomEvent) MarshalJSON() ([]byte, error) {
|
|||
// being base64 encoded which is the default for []byte.
|
||||
event := json.RawMessage(ore.Event)
|
||||
content := struct {
|
||||
Event *json.RawMessage
|
||||
VisibilityEventIDs []string
|
||||
LatestEventIDs []string
|
||||
AddsStateEventIDs []string
|
||||
RemovesStateEventIDs []string
|
||||
LastSentEventID string
|
||||
Event *json.RawMessage
|
||||
VisibilityEventIDs []string
|
||||
LatestEventIDs []string
|
||||
AddsStateEventIDs []string
|
||||
RemovesStateEventIDs []string
|
||||
LastSentEventID string
|
||||
StateBeforeAddsEventIDs []string
|
||||
StateBeforeRemovesEventIDs []string
|
||||
}{
|
||||
Event: &event,
|
||||
VisibilityEventIDs: ore.VisibilityEventIDs,
|
||||
LatestEventIDs: ore.LatestEventIDs,
|
||||
AddsStateEventIDs: ore.AddsStateEventIDs,
|
||||
RemovesStateEventIDs: ore.RemovesStateEventIDs,
|
||||
LastSentEventID: ore.LastSentEventID,
|
||||
Event: &event,
|
||||
LatestEventIDs: ore.LatestEventIDs,
|
||||
AddsStateEventIDs: ore.AddsStateEventIDs,
|
||||
RemovesStateEventIDs: ore.RemovesStateEventIDs,
|
||||
LastSentEventID: ore.LastSentEventID,
|
||||
StateBeforeAddsEventIDs: ore.StateBeforeAddsEventIDs,
|
||||
StateBeforeRemovesEventIDs: ore.StateBeforeRemovesEventIDs,
|
||||
}
|
||||
return json.Marshal(&content)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/matrix-org/dendrite/roomserver/state"
|
||||
"github.com/matrix-org/dendrite/roomserver/types"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/util"
|
||||
)
|
||||
|
||||
// updateLatestEvents updates the list of latest events for this room in the database and writes the
|
||||
|
|
@ -110,6 +111,13 @@ func doUpdateLatestEvents(
|
|||
return err
|
||||
}
|
||||
|
||||
stateBeforeEventRemoves, stateBeforeEventAdds, err := state.DifferenceBetweeenStateSnapshots(
|
||||
db, newStateNID, stateAtEvent.BeforeStateSnapshotNID,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Send the event to the output logs.
|
||||
// We do this inside the database transaction to ensure that we only mark an event as sent if we sent it.
|
||||
// (n.b. this means that it's possible that the same event will be sent twice if the transaction fails but
|
||||
|
|
@ -118,7 +126,10 @@ func doUpdateLatestEvents(
|
|||
// send the event asynchronously but we would need to ensure that 1) the events are written to the log in
|
||||
// the correct order, 2) that pending writes are resent across restarts. In order to avoid writing all the
|
||||
// necessary bookkeeping we'll keep the event sending synchronous for now.
|
||||
if err = writeEvent(db, ow, lastEventIDSent, event, newLatest, removed, added); err != nil {
|
||||
if err = writeEvent(
|
||||
db, ow, lastEventIDSent, event, newLatest, removed, added,
|
||||
stateBeforeEventRemoves, stateBeforeEventAdds,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +181,7 @@ func writeEvent(
|
|||
db RoomEventDatabase, ow OutputRoomEventWriter, lastEventIDSent string,
|
||||
event gomatrixserverlib.Event, latest []types.StateAtEventAndReference,
|
||||
removed, added []types.StateEntry,
|
||||
stateBeforeEventRemoves, stateBeforeEventAdds []types.StateEntry,
|
||||
) error {
|
||||
|
||||
latestEventIDs := make([]string, len(latest))
|
||||
|
|
@ -190,6 +202,13 @@ func writeEvent(
|
|||
for _, entry := range removed {
|
||||
stateEventNIDs = append(stateEventNIDs, entry.EventNID)
|
||||
}
|
||||
for _, entry := range stateBeforeEventRemoves {
|
||||
stateEventNIDs = append(stateEventNIDs, entry.EventNID)
|
||||
}
|
||||
for _, entry := range stateBeforeEventAdds {
|
||||
stateEventNIDs = append(stateEventNIDs, entry.EventNID)
|
||||
}
|
||||
stateEventNIDs = stateEventNIDs[:util.SortAndUnique(eventNIDSorter(stateEventNIDs))]
|
||||
eventIDMap, err := db.EventIDs(stateEventNIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -200,7 +219,18 @@ func writeEvent(
|
|||
for _, entry := range removed {
|
||||
ore.RemovesStateEventIDs = append(ore.RemovesStateEventIDs, eventIDMap[entry.EventNID])
|
||||
}
|
||||
|
||||
for _, entry := range stateBeforeEventRemoves {
|
||||
ore.StateBeforeRemovesEventIDs = append(ore.StateBeforeRemovesEventIDs, eventIDMap[entry.EventNID])
|
||||
}
|
||||
for _, entry := range stateBeforeEventAdds {
|
||||
ore.StateBeforeAddsEventIDs = append(ore.StateBeforeAddsEventIDs, eventIDMap[entry.EventNID])
|
||||
}
|
||||
// TODO: Fill out VisibilityStateIDs
|
||||
return ow.WriteOutputRoomEvent(ore)
|
||||
}
|
||||
|
||||
type eventNIDSorter []types.EventNID
|
||||
|
||||
func (s eventNIDSorter) Len() int { return len(s) }
|
||||
func (s eventNIDSorter) Less(i, j int) bool { return s[i] < s[j] }
|
||||
func (s eventNIDSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
|
|
|||
Loading…
Reference in a new issue