mirror of
https://github.com/1f349/dendrite.git
synced 2024-11-22 11:41:38 +00:00
State handling tweaks (#2652)
This tweaks how rejected events are handled in room state and also to not apply checks we can't complete to outliers.
This commit is contained in:
parent
606cb67506
commit
6b48ce0d75
@ -39,7 +39,7 @@ func CheckForSoftFail(
|
|||||||
var authStateEntries []types.StateEntry
|
var authStateEntries []types.StateEntry
|
||||||
var err error
|
var err error
|
||||||
if rewritesState {
|
if rewritesState {
|
||||||
authStateEntries, err = db.StateEntriesForEventIDs(ctx, stateEventIDs)
|
authStateEntries, err = db.StateEntriesForEventIDs(ctx, stateEventIDs, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, fmt.Errorf("StateEntriesForEventIDs failed: %w", err)
|
return true, fmt.Errorf("StateEntriesForEventIDs failed: %w", err)
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ func CheckAuthEvents(
|
|||||||
authEventIDs []string,
|
authEventIDs []string,
|
||||||
) ([]types.EventNID, error) {
|
) ([]types.EventNID, error) {
|
||||||
// Grab the numeric IDs for the supplied auth state events from the database.
|
// Grab the numeric IDs for the supplied auth state events from the database.
|
||||||
authStateEntries, err := db.StateEntriesForEventIDs(ctx, authEventIDs)
|
authStateEntries, err := db.StateEntriesForEventIDs(ctx, authEventIDs, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("db.StateEntriesForEventIDs: %w", err)
|
return nil, fmt.Errorf("db.StateEntriesForEventIDs: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -301,7 +301,7 @@ func (r *Inputer) processRoomEvent(
|
|||||||
// bother doing this if the event was already rejected as it just ends up
|
// bother doing this if the event was already rejected as it just ends up
|
||||||
// burning CPU time.
|
// burning CPU time.
|
||||||
historyVisibility := gomatrixserverlib.HistoryVisibilityShared // Default to shared.
|
historyVisibility := gomatrixserverlib.HistoryVisibilityShared // Default to shared.
|
||||||
if rejectionErr == nil && !isRejected && !softfail {
|
if input.Kind != api.KindOutlier && rejectionErr == nil && !isRejected && !softfail {
|
||||||
var err error
|
var err error
|
||||||
historyVisibility, rejectionErr, err = r.processStateBefore(ctx, input, missingPrev)
|
historyVisibility, rejectionErr, err = r.processStateBefore(ctx, input, missingPrev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -356,6 +356,8 @@ func (r *Inputer) processRoomEvent(
|
|||||||
// We stop here if the event is rejected: We've stored it but won't update forward extremities or notify anyone about it.
|
// We stop here if the event is rejected: We've stored it but won't update forward extremities or notify anyone about it.
|
||||||
if isRejected || softfail {
|
if isRejected || softfail {
|
||||||
logger.WithError(rejectionErr).WithFields(logrus.Fields{
|
logger.WithError(rejectionErr).WithFields(logrus.Fields{
|
||||||
|
"room_id": event.RoomID(),
|
||||||
|
"event_id": event.EventID(),
|
||||||
"soft_fail": softfail,
|
"soft_fail": softfail,
|
||||||
"missing_prev": missingPrev,
|
"missing_prev": missingPrev,
|
||||||
}).Warn("Stored rejected event")
|
}).Warn("Stored rejected event")
|
||||||
@ -661,7 +663,7 @@ func (r *Inputer) calculateAndSetState(
|
|||||||
// We've been told what the state at the event is so we don't need to calculate it.
|
// We've been told what the state at the event is so we don't need to calculate it.
|
||||||
// Check that those state events are in the database and store the state.
|
// Check that those state events are in the database and store the state.
|
||||||
var entries []types.StateEntry
|
var entries []types.StateEntry
|
||||||
if entries, err = r.DB.StateEntriesForEventIDs(ctx, input.StateEventIDs); err != nil {
|
if entries, err = r.DB.StateEntriesForEventIDs(ctx, input.StateEventIDs, true); err != nil {
|
||||||
return fmt.Errorf("updater.StateEntriesForEventIDs: %w", err)
|
return fmt.Errorf("updater.StateEntriesForEventIDs: %w", err)
|
||||||
}
|
}
|
||||||
entries = types.DeduplicateStateEntries(entries)
|
entries = types.DeduplicateStateEntries(entries)
|
||||||
|
@ -140,11 +140,11 @@ func (r *Backfiller) backfillViaFederation(ctx context.Context, req *api.Perform
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var entries []types.StateEntry
|
var entries []types.StateEntry
|
||||||
if entries, err = r.DB.StateEntriesForEventIDs(ctx, stateIDs); err != nil {
|
if entries, err = r.DB.StateEntriesForEventIDs(ctx, stateIDs, true); err != nil {
|
||||||
// attempt to fetch the missing events
|
// attempt to fetch the missing events
|
||||||
r.fetchAndStoreMissingEvents(ctx, info.RoomVersion, requester, stateIDs)
|
r.fetchAndStoreMissingEvents(ctx, info.RoomVersion, requester, stateIDs)
|
||||||
// try again
|
// try again
|
||||||
entries, err = r.DB.StateEntriesForEventIDs(ctx, stateIDs)
|
entries, err = r.DB.StateEntriesForEventIDs(ctx, stateIDs, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).WithField("event_id", ev.EventID()).Error("backfillViaFederation: failed to get state entries for event")
|
logrus.WithError(err).WithField("event_id", ev.EventID()).Error("backfillViaFederation: failed to get state entries for event")
|
||||||
return err
|
return err
|
||||||
|
@ -79,7 +79,7 @@ type Database interface {
|
|||||||
// Look up the state entries for a list of string event IDs
|
// Look up the state entries for a list of string event IDs
|
||||||
// Returns an error if the there is an error talking to the database
|
// Returns an error if the there is an error talking to the database
|
||||||
// Returns a types.MissingEventError if the event IDs aren't in the database.
|
// Returns a types.MissingEventError if the event IDs aren't in the database.
|
||||||
StateEntriesForEventIDs(ctx context.Context, eventIDs []string) ([]types.StateEntry, error)
|
StateEntriesForEventIDs(ctx context.Context, eventIDs []string, excludeRejected bool) ([]types.StateEntry, error)
|
||||||
// Look up the string event state keys for a list of numeric event state keys
|
// Look up the string event state keys for a list of numeric event state keys
|
||||||
// Returns an error if there was a problem talking to the database.
|
// Returns an error if there was a problem talking to the database.
|
||||||
EventStateKeys(ctx context.Context, eventStateKeyNIDs []types.EventStateKeyNID) (map[types.EventStateKeyNID]string, error)
|
EventStateKeys(ctx context.Context, eventStateKeyNIDs []types.EventStateKeyNID) (map[types.EventStateKeyNID]string, error)
|
||||||
|
@ -88,6 +88,14 @@ const bulkSelectStateEventByIDSQL = "" +
|
|||||||
" WHERE event_id = ANY($1)" +
|
" WHERE event_id = ANY($1)" +
|
||||||
" ORDER BY event_type_nid, event_state_key_nid ASC"
|
" ORDER BY event_type_nid, event_state_key_nid ASC"
|
||||||
|
|
||||||
|
// Bulk lookup of events by string ID that aren't excluded.
|
||||||
|
// Sort by the numeric IDs for event type and state key.
|
||||||
|
// This means we can use binary search to lookup entries by type and state key.
|
||||||
|
const bulkSelectStateEventByIDExcludingRejectedSQL = "" +
|
||||||
|
"SELECT event_type_nid, event_state_key_nid, event_nid FROM roomserver_events" +
|
||||||
|
" WHERE event_id = ANY($1) AND is_rejected = FALSE" +
|
||||||
|
" ORDER BY event_type_nid, event_state_key_nid ASC"
|
||||||
|
|
||||||
// Bulk look up of events by event NID, optionally filtering by the event type
|
// Bulk look up of events by event NID, optionally filtering by the event type
|
||||||
// or event state key NIDs if provided. (The CARDINALITY check will return true
|
// or event state key NIDs if provided. (The CARDINALITY check will return true
|
||||||
// if the provided arrays are empty, ergo no filtering).
|
// if the provided arrays are empty, ergo no filtering).
|
||||||
@ -140,23 +148,24 @@ const selectEventRejectedSQL = "" +
|
|||||||
"SELECT is_rejected FROM roomserver_events WHERE room_nid = $1 AND event_id = $2"
|
"SELECT is_rejected FROM roomserver_events WHERE room_nid = $1 AND event_id = $2"
|
||||||
|
|
||||||
type eventStatements struct {
|
type eventStatements struct {
|
||||||
insertEventStmt *sql.Stmt
|
insertEventStmt *sql.Stmt
|
||||||
selectEventStmt *sql.Stmt
|
selectEventStmt *sql.Stmt
|
||||||
bulkSelectStateEventByIDStmt *sql.Stmt
|
bulkSelectStateEventByIDStmt *sql.Stmt
|
||||||
bulkSelectStateEventByNIDStmt *sql.Stmt
|
bulkSelectStateEventByIDExcludingRejectedStmt *sql.Stmt
|
||||||
bulkSelectStateAtEventByIDStmt *sql.Stmt
|
bulkSelectStateEventByNIDStmt *sql.Stmt
|
||||||
updateEventStateStmt *sql.Stmt
|
bulkSelectStateAtEventByIDStmt *sql.Stmt
|
||||||
selectEventSentToOutputStmt *sql.Stmt
|
updateEventStateStmt *sql.Stmt
|
||||||
updateEventSentToOutputStmt *sql.Stmt
|
selectEventSentToOutputStmt *sql.Stmt
|
||||||
selectEventIDStmt *sql.Stmt
|
updateEventSentToOutputStmt *sql.Stmt
|
||||||
bulkSelectStateAtEventAndReferenceStmt *sql.Stmt
|
selectEventIDStmt *sql.Stmt
|
||||||
bulkSelectEventReferenceStmt *sql.Stmt
|
bulkSelectStateAtEventAndReferenceStmt *sql.Stmt
|
||||||
bulkSelectEventIDStmt *sql.Stmt
|
bulkSelectEventReferenceStmt *sql.Stmt
|
||||||
bulkSelectEventNIDStmt *sql.Stmt
|
bulkSelectEventIDStmt *sql.Stmt
|
||||||
bulkSelectUnsentEventNIDStmt *sql.Stmt
|
bulkSelectEventNIDStmt *sql.Stmt
|
||||||
selectMaxEventDepthStmt *sql.Stmt
|
bulkSelectUnsentEventNIDStmt *sql.Stmt
|
||||||
selectRoomNIDsForEventNIDsStmt *sql.Stmt
|
selectMaxEventDepthStmt *sql.Stmt
|
||||||
selectEventRejectedStmt *sql.Stmt
|
selectRoomNIDsForEventNIDsStmt *sql.Stmt
|
||||||
|
selectEventRejectedStmt *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateEventsTable(db *sql.DB) error {
|
func CreateEventsTable(db *sql.DB) error {
|
||||||
@ -171,6 +180,7 @@ func PrepareEventsTable(db *sql.DB) (tables.Events, error) {
|
|||||||
{&s.insertEventStmt, insertEventSQL},
|
{&s.insertEventStmt, insertEventSQL},
|
||||||
{&s.selectEventStmt, selectEventSQL},
|
{&s.selectEventStmt, selectEventSQL},
|
||||||
{&s.bulkSelectStateEventByIDStmt, bulkSelectStateEventByIDSQL},
|
{&s.bulkSelectStateEventByIDStmt, bulkSelectStateEventByIDSQL},
|
||||||
|
{&s.bulkSelectStateEventByIDExcludingRejectedStmt, bulkSelectStateEventByIDExcludingRejectedSQL},
|
||||||
{&s.bulkSelectStateEventByNIDStmt, bulkSelectStateEventByNIDSQL},
|
{&s.bulkSelectStateEventByNIDStmt, bulkSelectStateEventByNIDSQL},
|
||||||
{&s.bulkSelectStateAtEventByIDStmt, bulkSelectStateAtEventByIDSQL},
|
{&s.bulkSelectStateAtEventByIDStmt, bulkSelectStateAtEventByIDSQL},
|
||||||
{&s.updateEventStateStmt, updateEventStateSQL},
|
{&s.updateEventStateStmt, updateEventStateSQL},
|
||||||
@ -221,11 +231,18 @@ func (s *eventStatements) SelectEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// bulkSelectStateEventByID lookups a list of state events by event ID.
|
// bulkSelectStateEventByID lookups a list of state events by event ID.
|
||||||
// If any of the requested events are missing from the database it returns a types.MissingEventError
|
// If not excluding rejected events, and any of the requested events are missing from
|
||||||
|
// the database it returns a types.MissingEventError. If excluding rejected events,
|
||||||
|
// the events will be silently omitted without error.
|
||||||
func (s *eventStatements) BulkSelectStateEventByID(
|
func (s *eventStatements) BulkSelectStateEventByID(
|
||||||
ctx context.Context, txn *sql.Tx, eventIDs []string,
|
ctx context.Context, txn *sql.Tx, eventIDs []string, excludeRejected bool,
|
||||||
) ([]types.StateEntry, error) {
|
) ([]types.StateEntry, error) {
|
||||||
stmt := sqlutil.TxStmt(txn, s.bulkSelectStateEventByIDStmt)
|
var stmt *sql.Stmt
|
||||||
|
if excludeRejected {
|
||||||
|
stmt = sqlutil.TxStmt(txn, s.bulkSelectStateEventByIDExcludingRejectedStmt)
|
||||||
|
} else {
|
||||||
|
stmt = sqlutil.TxStmt(txn, s.bulkSelectStateEventByIDStmt)
|
||||||
|
}
|
||||||
rows, err := stmt.QueryContext(ctx, pq.StringArray(eventIDs))
|
rows, err := stmt.QueryContext(ctx, pq.StringArray(eventIDs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -235,10 +252,10 @@ func (s *eventStatements) BulkSelectStateEventByID(
|
|||||||
// because of the unique constraint on event IDs.
|
// because of the unique constraint on event IDs.
|
||||||
// So we can allocate an array of the correct size now.
|
// So we can allocate an array of the correct size now.
|
||||||
// We might get fewer results than IDs so we adjust the length of the slice before returning it.
|
// We might get fewer results than IDs so we adjust the length of the slice before returning it.
|
||||||
results := make([]types.StateEntry, len(eventIDs))
|
results := make([]types.StateEntry, 0, len(eventIDs))
|
||||||
i := 0
|
i := 0
|
||||||
for ; rows.Next(); i++ {
|
for ; rows.Next(); i++ {
|
||||||
result := &results[i]
|
var result types.StateEntry
|
||||||
if err = rows.Scan(
|
if err = rows.Scan(
|
||||||
&result.EventTypeNID,
|
&result.EventTypeNID,
|
||||||
&result.EventStateKeyNID,
|
&result.EventStateKeyNID,
|
||||||
@ -246,11 +263,12 @@ func (s *eventStatements) BulkSelectStateEventByID(
|
|||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
results = append(results, result)
|
||||||
}
|
}
|
||||||
if err = rows.Err(); err != nil {
|
if err = rows.Err(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if i != len(eventIDs) {
|
if !excludeRejected && i != len(eventIDs) {
|
||||||
// If there are fewer rows returned than IDs then we were asked to lookup event IDs we don't have.
|
// If there are fewer rows returned than IDs then we were asked to lookup event IDs we don't have.
|
||||||
// We don't know which ones were missing because we don't return the string IDs in the query.
|
// We don't know which ones were missing because we don't return the string IDs in the query.
|
||||||
// However it should be possible debug this by replaying queries or entries from the input kafka logs.
|
// However it should be possible debug this by replaying queries or entries from the input kafka logs.
|
||||||
|
@ -113,9 +113,9 @@ func (d *Database) eventStateKeyNIDs(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) StateEntriesForEventIDs(
|
func (d *Database) StateEntriesForEventIDs(
|
||||||
ctx context.Context, eventIDs []string,
|
ctx context.Context, eventIDs []string, excludeRejected bool,
|
||||||
) ([]types.StateEntry, error) {
|
) ([]types.StateEntry, error) {
|
||||||
return d.EventsTable.BulkSelectStateEventByID(ctx, nil, eventIDs)
|
return d.EventsTable.BulkSelectStateEventByID(ctx, nil, eventIDs, excludeRejected)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) StateEntriesForTuples(
|
func (d *Database) StateEntriesForTuples(
|
||||||
|
@ -65,6 +65,14 @@ const bulkSelectStateEventByIDSQL = "" +
|
|||||||
" WHERE event_id IN ($1)" +
|
" WHERE event_id IN ($1)" +
|
||||||
" ORDER BY event_type_nid, event_state_key_nid ASC"
|
" ORDER BY event_type_nid, event_state_key_nid ASC"
|
||||||
|
|
||||||
|
// Bulk lookup of events by string ID that aren't rejected.
|
||||||
|
// Sort by the numeric IDs for event type and state key.
|
||||||
|
// This means we can use binary search to lookup entries by type and state key.
|
||||||
|
const bulkSelectStateEventByIDExcludingRejectedSQL = "" +
|
||||||
|
"SELECT event_type_nid, event_state_key_nid, event_nid FROM roomserver_events" +
|
||||||
|
" WHERE event_id IN ($1) AND is_rejected = 0" +
|
||||||
|
" ORDER BY event_type_nid, event_state_key_nid ASC"
|
||||||
|
|
||||||
const bulkSelectStateEventByNIDSQL = "" +
|
const bulkSelectStateEventByNIDSQL = "" +
|
||||||
"SELECT event_type_nid, event_state_key_nid, event_nid FROM roomserver_events" +
|
"SELECT event_type_nid, event_state_key_nid, event_nid FROM roomserver_events" +
|
||||||
" WHERE event_nid IN ($1)"
|
" WHERE event_nid IN ($1)"
|
||||||
@ -113,19 +121,20 @@ const selectEventRejectedSQL = "" +
|
|||||||
"SELECT is_rejected FROM roomserver_events WHERE room_nid = $1 AND event_id = $2"
|
"SELECT is_rejected FROM roomserver_events WHERE room_nid = $1 AND event_id = $2"
|
||||||
|
|
||||||
type eventStatements struct {
|
type eventStatements struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
insertEventStmt *sql.Stmt
|
insertEventStmt *sql.Stmt
|
||||||
selectEventStmt *sql.Stmt
|
selectEventStmt *sql.Stmt
|
||||||
bulkSelectStateEventByIDStmt *sql.Stmt
|
bulkSelectStateEventByIDStmt *sql.Stmt
|
||||||
bulkSelectStateAtEventByIDStmt *sql.Stmt
|
bulkSelectStateEventByIDExcludingRejectedStmt *sql.Stmt
|
||||||
updateEventStateStmt *sql.Stmt
|
bulkSelectStateAtEventByIDStmt *sql.Stmt
|
||||||
selectEventSentToOutputStmt *sql.Stmt
|
updateEventStateStmt *sql.Stmt
|
||||||
updateEventSentToOutputStmt *sql.Stmt
|
selectEventSentToOutputStmt *sql.Stmt
|
||||||
selectEventIDStmt *sql.Stmt
|
updateEventSentToOutputStmt *sql.Stmt
|
||||||
bulkSelectStateAtEventAndReferenceStmt *sql.Stmt
|
selectEventIDStmt *sql.Stmt
|
||||||
bulkSelectEventReferenceStmt *sql.Stmt
|
bulkSelectStateAtEventAndReferenceStmt *sql.Stmt
|
||||||
bulkSelectEventIDStmt *sql.Stmt
|
bulkSelectEventReferenceStmt *sql.Stmt
|
||||||
selectEventRejectedStmt *sql.Stmt
|
bulkSelectEventIDStmt *sql.Stmt
|
||||||
|
selectEventRejectedStmt *sql.Stmt
|
||||||
//bulkSelectEventNIDStmt *sql.Stmt
|
//bulkSelectEventNIDStmt *sql.Stmt
|
||||||
//bulkSelectUnsentEventNIDStmt *sql.Stmt
|
//bulkSelectUnsentEventNIDStmt *sql.Stmt
|
||||||
//selectRoomNIDsForEventNIDsStmt *sql.Stmt
|
//selectRoomNIDsForEventNIDsStmt *sql.Stmt
|
||||||
@ -145,6 +154,7 @@ func PrepareEventsTable(db *sql.DB) (tables.Events, error) {
|
|||||||
{&s.insertEventStmt, insertEventSQL},
|
{&s.insertEventStmt, insertEventSQL},
|
||||||
{&s.selectEventStmt, selectEventSQL},
|
{&s.selectEventStmt, selectEventSQL},
|
||||||
{&s.bulkSelectStateEventByIDStmt, bulkSelectStateEventByIDSQL},
|
{&s.bulkSelectStateEventByIDStmt, bulkSelectStateEventByIDSQL},
|
||||||
|
{&s.bulkSelectStateEventByIDExcludingRejectedStmt, bulkSelectStateEventByIDExcludingRejectedSQL},
|
||||||
{&s.bulkSelectStateAtEventByIDStmt, bulkSelectStateAtEventByIDSQL},
|
{&s.bulkSelectStateAtEventByIDStmt, bulkSelectStateAtEventByIDSQL},
|
||||||
{&s.updateEventStateStmt, updateEventStateSQL},
|
{&s.updateEventStateStmt, updateEventStateSQL},
|
||||||
{&s.updateEventSentToOutputStmt, updateEventSentToOutputSQL},
|
{&s.updateEventSentToOutputStmt, updateEventSentToOutputSQL},
|
||||||
@ -194,16 +204,24 @@ func (s *eventStatements) SelectEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// bulkSelectStateEventByID lookups a list of state events by event ID.
|
// bulkSelectStateEventByID lookups a list of state events by event ID.
|
||||||
// If any of the requested events are missing from the database it returns a types.MissingEventError
|
// If not excluding rejected events, and any of the requested events are missing from
|
||||||
|
// the database it returns a types.MissingEventError. If excluding rejected events,
|
||||||
|
// the events will be silently omitted without error.
|
||||||
func (s *eventStatements) BulkSelectStateEventByID(
|
func (s *eventStatements) BulkSelectStateEventByID(
|
||||||
ctx context.Context, txn *sql.Tx, eventIDs []string,
|
ctx context.Context, txn *sql.Tx, eventIDs []string, excludeRejected bool,
|
||||||
) ([]types.StateEntry, error) {
|
) ([]types.StateEntry, error) {
|
||||||
///////////////
|
///////////////
|
||||||
|
var sql string
|
||||||
|
if excludeRejected {
|
||||||
|
sql = bulkSelectStateEventByIDExcludingRejectedSQL
|
||||||
|
} else {
|
||||||
|
sql = bulkSelectStateEventByIDSQL
|
||||||
|
}
|
||||||
iEventIDs := make([]interface{}, len(eventIDs))
|
iEventIDs := make([]interface{}, len(eventIDs))
|
||||||
for k, v := range eventIDs {
|
for k, v := range eventIDs {
|
||||||
iEventIDs[k] = v
|
iEventIDs[k] = v
|
||||||
}
|
}
|
||||||
selectOrig := strings.Replace(bulkSelectStateEventByIDSQL, "($1)", sqlutil.QueryVariadic(len(iEventIDs)), 1)
|
selectOrig := strings.Replace(sql, "($1)", sqlutil.QueryVariadic(len(iEventIDs)), 1)
|
||||||
selectPrep, err := s.db.Prepare(selectOrig)
|
selectPrep, err := s.db.Prepare(selectOrig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -221,10 +239,10 @@ func (s *eventStatements) BulkSelectStateEventByID(
|
|||||||
// because of the unique constraint on event IDs.
|
// because of the unique constraint on event IDs.
|
||||||
// So we can allocate an array of the correct size now.
|
// So we can allocate an array of the correct size now.
|
||||||
// We might get fewer results than IDs so we adjust the length of the slice before returning it.
|
// We might get fewer results than IDs so we adjust the length of the slice before returning it.
|
||||||
results := make([]types.StateEntry, len(eventIDs))
|
results := make([]types.StateEntry, 0, len(eventIDs))
|
||||||
i := 0
|
i := 0
|
||||||
for ; rows.Next(); i++ {
|
for ; rows.Next(); i++ {
|
||||||
result := &results[i]
|
var result types.StateEntry
|
||||||
if err = rows.Scan(
|
if err = rows.Scan(
|
||||||
&result.EventTypeNID,
|
&result.EventTypeNID,
|
||||||
&result.EventStateKeyNID,
|
&result.EventStateKeyNID,
|
||||||
@ -232,8 +250,9 @@ func (s *eventStatements) BulkSelectStateEventByID(
|
|||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
results = append(results, result)
|
||||||
}
|
}
|
||||||
if i != len(eventIDs) {
|
if !excludeRejected && i != len(eventIDs) {
|
||||||
// If there are fewer rows returned than IDs then we were asked to lookup event IDs we don't have.
|
// If there are fewer rows returned than IDs then we were asked to lookup event IDs we don't have.
|
||||||
// We don't know which ones were missing because we don't return the string IDs in the query.
|
// We don't know which ones were missing because we don't return the string IDs in the query.
|
||||||
// However it should be possible debug this by replaying queries or entries from the input kafka logs.
|
// However it should be possible debug this by replaying queries or entries from the input kafka logs.
|
||||||
|
@ -102,7 +102,7 @@ func Test_EventsTable(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
stateEvents, err := tab.BulkSelectStateEventByID(ctx, nil, eventIDs)
|
stateEvents, err := tab.BulkSelectStateEventByID(ctx, nil, eventIDs, false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, len(stateEvents), len(eventIDs))
|
assert.Equal(t, len(stateEvents), len(eventIDs))
|
||||||
nids := make([]types.EventNID, 0, len(stateEvents))
|
nids := make([]types.EventNID, 0, len(stateEvents))
|
||||||
|
@ -46,7 +46,7 @@ type Events interface {
|
|||||||
SelectEvent(ctx context.Context, txn *sql.Tx, eventID string) (types.EventNID, types.StateSnapshotNID, error)
|
SelectEvent(ctx context.Context, txn *sql.Tx, eventID string) (types.EventNID, types.StateSnapshotNID, error)
|
||||||
// bulkSelectStateEventByID lookups a list of state events by event ID.
|
// bulkSelectStateEventByID lookups a list of state events by event ID.
|
||||||
// If any of the requested events are missing from the database it returns a types.MissingEventError
|
// If any of the requested events are missing from the database it returns a types.MissingEventError
|
||||||
BulkSelectStateEventByID(ctx context.Context, txn *sql.Tx, eventIDs []string) ([]types.StateEntry, error)
|
BulkSelectStateEventByID(ctx context.Context, txn *sql.Tx, eventIDs []string, excludeRejected bool) ([]types.StateEntry, error)
|
||||||
BulkSelectStateEventByNID(ctx context.Context, txn *sql.Tx, eventNIDs []types.EventNID, stateKeyTuples []types.StateKeyTuple) ([]types.StateEntry, error)
|
BulkSelectStateEventByNID(ctx context.Context, txn *sql.Tx, eventNIDs []types.EventNID, stateKeyTuples []types.StateKeyTuple) ([]types.StateEntry, error)
|
||||||
// BulkSelectStateAtEventByID lookups the state at a list of events by event ID.
|
// BulkSelectStateAtEventByID lookups the state at a list of events by event ID.
|
||||||
// If any of the requested events are missing from the database it returns a types.MissingEventError.
|
// If any of the requested events are missing from the database it returns a types.MissingEventError.
|
||||||
|
Loading…
Reference in New Issue
Block a user