diff --git a/syncapi/storage/interface.go b/syncapi/storage/interface.go index 57ba2c2a7..ca00e3a2e 100644 --- a/syncapi/storage/interface.go +++ b/syncapi/storage/interface.go @@ -150,7 +150,7 @@ type Database interface { // RedactEvent wipes an event in the database and sets the unsigned.redacted_because key to the redaction event RedactEvent(ctx context.Context, redactedEventID string, redactedBecause *gomatrixserverlib.HeaderedEvent) error // StoreReceipt stores new receipt events ofr - StoreReceipt(ctx context.Context, roomId, receiptType, userId, eventId string, timestamp gomatrixserverlib.Timestamp) error + StoreReceipt(ctx context.Context, roomId, receiptType, userId, eventId string, timestamp gomatrixserverlib.Timestamp) (pos types.StreamPosition, err error) // GetRoomReceipts gets all receipts for a given roomID GetRoomReceipts(ctx context.Context, roomId string, streamPos types.StreamPosition) ([]eduAPI.InputReceiptEvent, error) } diff --git a/syncapi/storage/shared/syncserver.go b/syncapi/storage/shared/syncserver.go index 74a640aab..804a097a1 100644 --- a/syncapi/storage/shared/syncserver.go +++ b/syncapi/storage/shared/syncserver.go @@ -21,6 +21,8 @@ import ( "fmt" "time" + "github.com/pkg/errors" + eduAPI "github.com/matrix-org/dendrite/eduserver/api" userapi "github.com/matrix-org/dendrite/userapi/api" @@ -565,11 +567,17 @@ func (d *Database) addTypingDeltaToResponse( return nil } -func (d *Database) addReceiptDeltaToResponse(since types.StreamPosition, joinedRoomIDs []string, res *types.Response) error { +// addReceiptDeltaToResponse adds all receipt information to a sync response +// since the specified position +func (d *Database) addReceiptDeltaToResponse( + since types.StreamingToken, + joinedRoomIDs []string, + res *types.Response, +) error { var jr types.JoinResponse // check all joinedRooms for receipts for _, roomID := range joinedRoomIDs { - receipts, err := d.Receipts.SelectRoomReceiptsAfter(context.TODO(), roomID, since) + receipts, err := d.Receipts.SelectRoomReceiptsAfter(context.TODO(), roomID, since.EDUPosition()) if err != nil { return err } @@ -609,19 +617,20 @@ func (d *Database) addEDUDeltaToResponse( fromPos, toPos types.StreamingToken, joinedRoomIDs []string, res *types.Response, -) (err error) { +) error { if fromPos.EDUPosition() != toPos.EDUPosition() { // add typing deltas if err := d.addTypingDeltaToResponse(fromPos, joinedRoomIDs, res); err != nil { - return - } - // add receipt deltas - if err := d.addReceiptDeltaToResponse(fromPos.EDUPosition(), joinedRoomIDs, res); err != nil { - return + return errors.Wrap(err, "unable to apply typing delta to response") } } - return + // always check for receipt deltas; otherwise an initial sync won't receive receipts + if err := d.addReceiptDeltaToResponse(fromPos, joinedRoomIDs, res); err != nil { + return errors.Wrap(err, "unable to apply receipts to response") + } + + return nil } func (d *Database) GetFilter( @@ -1459,11 +1468,12 @@ type stateDelta struct { } // StoreReceipt stores user receipts -func (d *Database) StoreReceipt(ctx context.Context, roomId, receiptType, userId, eventId string, timestamp gomatrixserverlib.Timestamp) error { - return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error { - _, err := d.Receipts.UpsertReceipt(ctx, txn, roomId, receiptType, userId, eventId, timestamp) +func (d *Database) StoreReceipt(ctx context.Context, roomId, receiptType, userId, eventId string, timestamp gomatrixserverlib.Timestamp) (pos types.StreamPosition, err error) { + err = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error { + pos, err = d.Receipts.UpsertReceipt(ctx, txn, roomId, receiptType, userId, eventId, timestamp) return err }) + return } func (d *Database) GetRoomReceipts(ctx context.Context, roomId string, streamPos types.StreamPosition) ([]eduAPI.InputReceiptEvent, error) { diff --git a/syncapi/storage/sqlite3/receipt_table.go b/syncapi/storage/sqlite3/receipt_table.go index 802570ea2..8d62a6554 100644 --- a/syncapi/storage/sqlite3/receipt_table.go +++ b/syncapi/storage/sqlite3/receipt_table.go @@ -49,7 +49,7 @@ const upsertReceipt = "" + " (id, room_id, receipt_type, user_id, event_id, receipt_ts)" + " VALUES ($1, $2, $3, $4, $5, $6)" + " ON CONFLICT (room_id, receipt_type, user_id)" + - " DO UPDATE SET id = $1, event_id = $4, receipt_ts = $5" + " DO UPDATE SET id = $1, event_id = $5, receipt_ts = $6" const selectRoomReceipts = "" + "SELECT room_id, receipt_type, user_id, event_id, receipt_ts" +