nil PDUs/EDUs shouldn't happen but guard against them for safety
This commit is contained in:
parent
7faef15339
commit
6029c79dfa
|
@ -69,6 +69,10 @@ type destinationQueue struct {
|
||||||
// If the queue is empty then it starts a background goroutine to
|
// If the queue is empty then it starts a background goroutine to
|
||||||
// start sending events to that destination.
|
// start sending events to that destination.
|
||||||
func (oq *destinationQueue) sendEvent(event *gomatrixserverlib.HeaderedEvent, receipt *shared.Receipt) {
|
func (oq *destinationQueue) sendEvent(event *gomatrixserverlib.HeaderedEvent, receipt *shared.Receipt) {
|
||||||
|
if event == nil {
|
||||||
|
log.Errorf("attempt to send nil PDU with destination %q", oq.destination)
|
||||||
|
return
|
||||||
|
}
|
||||||
// Create a transaction ID. We'll either do this if we don't have
|
// Create a transaction ID. We'll either do this if we don't have
|
||||||
// one made up yet, or if we've exceeded the number of maximum
|
// one made up yet, or if we've exceeded the number of maximum
|
||||||
// events allowed in a single tranaction. We'll reset the counter
|
// events allowed in a single tranaction. We'll reset the counter
|
||||||
|
@ -116,6 +120,10 @@ func (oq *destinationQueue) sendEvent(event *gomatrixserverlib.HeaderedEvent, re
|
||||||
// If the queue is empty then it starts a background goroutine to
|
// If the queue is empty then it starts a background goroutine to
|
||||||
// start sending events to that destination.
|
// start sending events to that destination.
|
||||||
func (oq *destinationQueue) sendEDU(event *gomatrixserverlib.EDU, receipt *shared.Receipt) {
|
func (oq *destinationQueue) sendEDU(event *gomatrixserverlib.EDU, receipt *shared.Receipt) {
|
||||||
|
if event == nil {
|
||||||
|
log.Errorf("attempt to send nil EDU with destination %q", oq.destination)
|
||||||
|
return
|
||||||
|
}
|
||||||
// Create a database entry that associates the given PDU NID with
|
// Create a database entry that associates the given PDU NID with
|
||||||
// this destination queue. We'll then be able to retrieve the PDU
|
// this destination queue. We'll then be able to retrieve the PDU
|
||||||
// later.
|
// later.
|
||||||
|
@ -370,6 +378,9 @@ func (oq *destinationQueue) nextTransaction(
|
||||||
// Go through PDUs that we retrieved from the database, if any,
|
// Go through PDUs that we retrieved from the database, if any,
|
||||||
// and add them into the transaction.
|
// and add them into the transaction.
|
||||||
for _, pdu := range pdus {
|
for _, pdu := range pdus {
|
||||||
|
if pdu.pdu == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// Append the JSON of the event, since this is a json.RawMessage type in the
|
// Append the JSON of the event, since this is a json.RawMessage type in the
|
||||||
// gomatrixserverlib.Transaction struct
|
// gomatrixserverlib.Transaction struct
|
||||||
t.PDUs = append(t.PDUs, pdu.pdu.JSON())
|
t.PDUs = append(t.PDUs, pdu.pdu.JSON())
|
||||||
|
@ -378,6 +389,9 @@ func (oq *destinationQueue) nextTransaction(
|
||||||
|
|
||||||
// Do the same for pending EDUS in the queue.
|
// Do the same for pending EDUS in the queue.
|
||||||
for _, edu := range edus {
|
for _, edu := range edus {
|
||||||
|
if edu.edu == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
t.EDUs = append(t.EDUs, *edu.edu)
|
t.EDUs = append(t.EDUs, *edu.edu)
|
||||||
eduReceipts = append(pduReceipts, edu.receipt)
|
eduReceipts = append(pduReceipts, edu.receipt)
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,15 +52,11 @@ func (d *Database) GetPendingEDUs(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
serverName gomatrixserverlib.ServerName,
|
serverName gomatrixserverlib.ServerName,
|
||||||
limit int,
|
limit int,
|
||||||
) (
|
) (map[*Receipt]*gomatrixserverlib.EDU, error) {
|
||||||
edus map[*Receipt]*gomatrixserverlib.EDU,
|
edus := make(map[*Receipt]*gomatrixserverlib.EDU)
|
||||||
err error,
|
nids, err := d.FederationSenderQueueEDUs.SelectQueueEDUs(ctx, nil, serverName, limit)
|
||||||
) {
|
|
||||||
edus = make(map[*Receipt]*gomatrixserverlib.EDU)
|
|
||||||
err = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
|
||||||
nids, err := d.FederationSenderQueueEDUs.SelectQueueEDUs(ctx, txn, serverName, limit)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("SelectQueueEDUs: %w", err)
|
return nil, fmt.Errorf("SelectQueueEDUs: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
retrieve := make([]int64, 0, len(nids))
|
retrieve := make([]int64, 0, len(nids))
|
||||||
|
@ -72,22 +68,20 @@ func (d *Database) GetPendingEDUs(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blobs, err := d.FederationSenderQueueJSON.SelectQueueJSON(ctx, txn, retrieve)
|
blobs, err := d.FederationSenderQueueJSON.SelectQueueJSON(ctx, nil, retrieve)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("SelectQueueJSON: %w", err)
|
return nil, fmt.Errorf("SelectQueueJSON: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for nid, blob := range blobs {
|
for nid, blob := range blobs {
|
||||||
var event gomatrixserverlib.EDU
|
var event gomatrixserverlib.EDU
|
||||||
if err := json.Unmarshal(blob, &event); err != nil {
|
if err := json.Unmarshal(blob, &event); err != nil {
|
||||||
return fmt.Errorf("json.Unmarshal: %w", err)
|
return nil, fmt.Errorf("json.Unmarshal: %w", err)
|
||||||
}
|
}
|
||||||
edus[&Receipt{nid}] = &event
|
edus[&Receipt{nid}] = &event
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return edus, nil
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanEDUs cleans up all specified EDUs. This is done when a
|
// CleanEDUs cleans up all specified EDUs. This is done when a
|
||||||
|
|
|
@ -53,20 +53,16 @@ func (d *Database) GetPendingPDUs(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
serverName gomatrixserverlib.ServerName,
|
serverName gomatrixserverlib.ServerName,
|
||||||
limit int,
|
limit int,
|
||||||
) (
|
) (map[*Receipt]*gomatrixserverlib.HeaderedEvent, error) {
|
||||||
events map[*Receipt]*gomatrixserverlib.HeaderedEvent,
|
|
||||||
err error,
|
|
||||||
) {
|
|
||||||
// Strictly speaking this doesn't need to be using the writer
|
// Strictly speaking this doesn't need to be using the writer
|
||||||
// since we are only performing selects, but since we don't have
|
// since we are only performing selects, but since we don't have
|
||||||
// a guarantee of transactional isolation, it's actually useful
|
// a guarantee of transactional isolation, it's actually useful
|
||||||
// to know in SQLite mode that nothing else is trying to modify
|
// to know in SQLite mode that nothing else is trying to modify
|
||||||
// the database.
|
// the database.
|
||||||
events = make(map[*Receipt]*gomatrixserverlib.HeaderedEvent)
|
events := make(map[*Receipt]*gomatrixserverlib.HeaderedEvent)
|
||||||
err = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
nids, err := d.FederationSenderQueuePDUs.SelectQueuePDUs(ctx, nil, serverName, limit)
|
||||||
nids, err := d.FederationSenderQueuePDUs.SelectQueuePDUs(ctx, txn, serverName, limit)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("SelectQueuePDUs: %w", err)
|
return nil, fmt.Errorf("SelectQueuePDUs: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
retrieve := make([]int64, 0, len(nids))
|
retrieve := make([]int64, 0, len(nids))
|
||||||
|
@ -78,23 +74,21 @@ func (d *Database) GetPendingPDUs(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blobs, err := d.FederationSenderQueueJSON.SelectQueueJSON(ctx, txn, retrieve)
|
blobs, err := d.FederationSenderQueueJSON.SelectQueueJSON(ctx, nil, retrieve)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("SelectQueueJSON: %w", err)
|
return nil, fmt.Errorf("SelectQueueJSON: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for nid, blob := range blobs {
|
for nid, blob := range blobs {
|
||||||
var event gomatrixserverlib.HeaderedEvent
|
var event gomatrixserverlib.HeaderedEvent
|
||||||
if err := json.Unmarshal(blob, &event); err != nil {
|
if err := json.Unmarshal(blob, &event); err != nil {
|
||||||
return fmt.Errorf("json.Unmarshal: %w", err)
|
return nil, fmt.Errorf("json.Unmarshal: %w", err)
|
||||||
}
|
}
|
||||||
events[&Receipt{nid}] = &event
|
events[&Receipt{nid}] = &event
|
||||||
d.Cache.StoreFederationSenderQueuedPDU(nid, &event)
|
d.Cache.StoreFederationSenderQueuedPDU(nid, &event)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return events, nil
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanTransactionPDUs cleans up all associated events for a
|
// CleanTransactionPDUs cleans up all associated events for a
|
||||||
|
|
Loading…
Reference in a new issue