#903: Client API: mutex on (user_id, room_id) (#1286)

* 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 it
This commit is contained in:
anandv96 2020-08-20 12:57:43 +05:30 committed by GitHub
parent b24747b305
commit f5edfb9659
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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