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),

60
user.go
View file

@ -57,8 +57,9 @@ type User struct {
Whitelisted bool Whitelisted bool
RelayWhitelisted bool RelayWhitelisted bool
mgmtCreateLock sync.Mutex mgmtCreateLock sync.Mutex
connLock sync.Mutex spaceCreateLock sync.Mutex
connLock sync.Mutex
historySyncs chan *events.HistorySync historySyncs chan *events.HistorySync
prevBridgeStatus *BridgeState prevBridgeStatus *BridgeState
@ -182,45 +183,50 @@ 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
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) if len(user.SpaceRoom) != 0 {
var invite []id.UserID roomID = user.SpaceRoom
invite = append(invite, user.MXID) user.log.Debugln("Returning space after lock" + user.SpaceRoom)
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 { } 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 { } 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()