* Client API: mutex on (user_id, room_id) * Client API: mutex on (user_id, room_id) Changed variable name used for the mutexes map Changed the place where the mutex is locked Changed unlock to a defered call instead of manually calling itmain
parent
b24747b305
commit
f5edfb9659
|
@ -16,6 +16,7 @@ package routing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
|
@ -35,6 +36,10 @@ type sendEventResponse struct {
|
||||||
EventID string `json:"event_id"`
|
EventID string `json:"event_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
userRoomSendMutexes sync.Map // (roomID+userID) -> mutex. mutexes to ensure correct ordering of sendEvents
|
||||||
|
)
|
||||||
|
|
||||||
// SendEvent implements:
|
// SendEvent implements:
|
||||||
// /rooms/{roomID}/send/{eventType}
|
// /rooms/{roomID}/send/{eventType}
|
||||||
// /rooms/{roomID}/send/{eventType}/{txnID}
|
// /rooms/{roomID}/send/{eventType}/{txnID}
|
||||||
|
@ -63,6 +68,13 @@ func SendEvent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create a mutex for the specific user in the specific room
|
||||||
|
// this avoids a situation where events that are received in quick succession are sent to the roomserver in a jumbled order
|
||||||
|
userID := device.UserID
|
||||||
|
mutex, _ := userRoomSendMutexes.LoadOrStore(roomID+userID, &sync.Mutex{})
|
||||||
|
mutex.(*sync.Mutex).Lock()
|
||||||
|
defer mutex.(*sync.Mutex).Unlock()
|
||||||
|
|
||||||
e, resErr := generateSendEvent(req, device, roomID, eventType, stateKey, cfg, rsAPI)
|
e, resErr := generateSendEvent(req, device, roomID, eventType, stateKey, cfg, rsAPI)
|
||||||
if resErr != nil {
|
if resErr != nil {
|
||||||
return *resErr
|
return *resErr
|
||||||
|
|
Loading…
Reference in New Issue