From dfa845efb433c799d01831968cd7d7207e87460b Mon Sep 17 00:00:00 2001 From: Helder Ferreira Date: Wed, 29 Dec 2021 12:19:16 +0000 Subject: [PATCH] Fix concurrency issues creating/getting the space --- main.go | 4 +++- user.go | 60 +++++++++++++++++++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/main.go b/main.go index 2bd520d..e210ec6 100644 --- a/main.go +++ b/main.go @@ -180,8 +180,9 @@ type Bridge struct { usersByUsername map[string]*User usersLock sync.Mutex spaceRooms map[id.RoomID]*User - managementRoomsLock sync.Mutex + spaceRoomsLock sync.Mutex managementRooms map[id.RoomID]*User + managementRoomsLock sync.Mutex portalsByMXID map[id.RoomID]*Portal portalsByJID map[database.PortalKey]*Portal portalsLock sync.Mutex @@ -480,6 +481,7 @@ func main() { (&Bridge{ usersByMXID: make(map[id.UserID]*User), usersByUsername: make(map[string]*User), + spaceRooms: make(map[id.RoomID]*User), managementRooms: make(map[id.RoomID]*User), portalsByMXID: make(map[id.RoomID]*Portal), portalsByJID: make(map[database.PortalKey]*Portal), diff --git a/user.go b/user.go index eae77cc..ec7da6f 100644 --- a/user.go +++ b/user.go @@ -57,8 +57,9 @@ type User struct { Whitelisted bool RelayWhitelisted bool - mgmtCreateLock sync.Mutex - connLock sync.Mutex + mgmtCreateLock sync.Mutex + spaceCreateLock sync.Mutex + connLock sync.Mutex historySyncs chan *events.HistorySync prevBridgeStatus *BridgeState @@ -182,45 +183,50 @@ func (bridge *Bridge) NewUser(dbUser *database.User) *User { func (user *User) getSpaceRoom() id.RoomID { var roomID id.RoomID - user.log.Debugln("getSpaceRoom called") - if len(user.SpaceRoom) == 0 { //TODO check if Spaces creation is enabled by config - creationContent := make(map[string]interface{}) - creationContent["type"] = "m.space" - user.log.Debugln("Creating a new space for the user") + //Create Space + user.log.Debugln("Locking to create space.") + user.spaceCreateLock.Lock() + defer user.spaceCreateLock.Unlock() - user.log.Debugln("Inviting user " + user.MXID) - var invite []id.UserID - invite = append(invite, user.MXID) - - resp, err := user.bridge.Bot.CreateRoom(&mautrix.ReqCreateRoom{ - Visibility: "private", - Name: "WhatsApp", - Topic: "WhatsApp bridge Space", - Invite: invite, - CreationContent: creationContent, - }) - if err != nil { - user.log.Errorln("Failed to auto-create space room:", err) + if len(user.SpaceRoom) != 0 { + roomID = user.SpaceRoom + user.log.Debugln("Returning space after lock" + user.SpaceRoom) } else { - user.setSpaceRoom(resp.RoomID) + creationContent := make(map[string]interface{}) + creationContent["type"] = "m.space" + + user.log.Debugln("Creating a new space for the user") + + user.log.Debugln("Inviting user " + user.MXID) + var invite []id.UserID + invite = append(invite, user.MXID) + + resp, err := user.bridge.Bot.CreateRoom(&mautrix.ReqCreateRoom{ + Visibility: "private", + Name: "WhatsApp", + Topic: "WhatsApp bridge Space", + Invite: invite, + CreationContent: creationContent, + }) + if err != nil { + user.log.Errorln("Failed to auto-create space room:", err) + } else { + user.setSpaceRoom(resp.RoomID) + roomID = resp.RoomID + } } } else { user.log.Debugln("Space found" + user.SpaceRoom) roomID = user.SpaceRoom } + return roomID } func (user *User) setSpaceRoom(spaceID id.RoomID) { - existingUser, ok := user.bridge.spaceRooms[spaceID] - if ok { - existingUser.SpaceRoom = "" - existingUser.Update() - } - user.SpaceRoom = spaceID user.bridge.spaceRooms[user.SpaceRoom] = user user.Update()