Fix concurrency issues creating/getting the space

This commit is contained in:
Helder Ferreira 2021-12-29 12:19:16 +00:00
parent 0a8bd7794b
commit dfa845efb4
No known key found for this signature in database
GPG key ID: 3848724EAD604B85
2 changed files with 36 additions and 28 deletions

View file

@ -180,8 +180,9 @@ type Bridge struct {
usersByUsername map[string]*User usersByUsername map[string]*User
usersLock sync.Mutex usersLock sync.Mutex
spaceRooms map[id.RoomID]*User spaceRooms map[id.RoomID]*User
managementRoomsLock sync.Mutex spaceRoomsLock sync.Mutex
managementRooms map[id.RoomID]*User managementRooms map[id.RoomID]*User
managementRoomsLock sync.Mutex
portalsByMXID map[id.RoomID]*Portal portalsByMXID map[id.RoomID]*Portal
portalsByJID map[database.PortalKey]*Portal portalsByJID map[database.PortalKey]*Portal
portalsLock sync.Mutex portalsLock sync.Mutex
@ -480,6 +481,7 @@ func main() {
(&Bridge{ (&Bridge{
usersByMXID: make(map[id.UserID]*User), usersByMXID: make(map[id.UserID]*User),
usersByUsername: make(map[string]*User), usersByUsername: make(map[string]*User),
spaceRooms: make(map[id.RoomID]*User),
managementRooms: make(map[id.RoomID]*User), managementRooms: make(map[id.RoomID]*User),
portalsByMXID: make(map[id.RoomID]*Portal), portalsByMXID: make(map[id.RoomID]*Portal),
portalsByJID: make(map[database.PortalKey]*Portal), portalsByJID: make(map[database.PortalKey]*Portal),

22
user.go
View file

@ -58,6 +58,7 @@ type User struct {
RelayWhitelisted bool RelayWhitelisted bool
mgmtCreateLock sync.Mutex mgmtCreateLock sync.Mutex
spaceCreateLock sync.Mutex
connLock sync.Mutex connLock sync.Mutex
historySyncs chan *events.HistorySync historySyncs chan *events.HistorySync
@ -182,10 +183,18 @@ func (bridge *Bridge) NewUser(dbUser *database.User) *User {
func (user *User) getSpaceRoom() id.RoomID { func (user *User) getSpaceRoom() id.RoomID {
var roomID id.RoomID var roomID id.RoomID
user.log.Debugln("getSpaceRoom called")
if len(user.SpaceRoom) == 0 { if len(user.SpaceRoom) == 0 {
//TODO check if Spaces creation is enabled by config //TODO check if Spaces creation is enabled by config
//Create Space
user.log.Debugln("Locking to create space.")
user.spaceCreateLock.Lock()
defer user.spaceCreateLock.Unlock()
if len(user.SpaceRoom) != 0 {
roomID = user.SpaceRoom
user.log.Debugln("Returning space after lock" + user.SpaceRoom)
} else {
creationContent := make(map[string]interface{}) creationContent := make(map[string]interface{})
creationContent["type"] = "m.space" creationContent["type"] = "m.space"
@ -206,21 +215,18 @@ func (user *User) getSpaceRoom() id.RoomID {
user.log.Errorln("Failed to auto-create space room:", err) user.log.Errorln("Failed to auto-create space room:", err)
} else { } else {
user.setSpaceRoom(resp.RoomID) user.setSpaceRoom(resp.RoomID)
roomID = resp.RoomID
}
} }
} else { } else {
user.log.Debugln("Space found" + user.SpaceRoom) user.log.Debugln("Space found" + user.SpaceRoom)
roomID = user.SpaceRoom roomID = user.SpaceRoom
} }
return roomID return roomID
} }
func (user *User) setSpaceRoom(spaceID id.RoomID) { func (user *User) setSpaceRoom(spaceID id.RoomID) {
existingUser, ok := user.bridge.spaceRooms[spaceID]
if ok {
existingUser.SpaceRoom = ""
existingUser.Update()
}
user.SpaceRoom = spaceID user.SpaceRoom = spaceID
user.bridge.spaceRooms[user.SpaceRoom] = user user.bridge.spaceRooms[user.SpaceRoom] = user
user.Update() user.Update()