Skip to content

Commit

Permalink
fix: reduce the granularity of the lock.
Browse files Browse the repository at this point in the history
  • Loading branch information
FGadvancer committed Dec 13, 2023
1 parent 4fccafa commit d958056
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 16 deletions.
2 changes: 1 addition & 1 deletion internal/msggateway/n_ws_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func NewWsServer(opts ...Option) (*WsServer, error) {
unregisterChan: make(chan *Client, 1000),
kickHandlerChan: make(chan *kickHandler, 1000),
validate: v,
clients: newUserMap(),
clients: newUserMap(10),
Compressor: NewGzipCompressor(),
Encoder: NewGobEncoder(),
}, nil
Expand Down
47 changes: 32 additions & 15 deletions internal/msggateway/user_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,43 @@ package msggateway

import (
"context"
"hash/fnv"
"sync"

"github.com/OpenIMSDK/tools/log"
"github.com/OpenIMSDK/tools/utils"
)

type UserMap struct {
m sync.Map
maps []sync.Map
}

func newUserMap() *UserMap {
return &UserMap{}
func newUserMap(numMaps int) *UserMap {
um := &UserMap{
maps: make([]sync.Map, numMaps),
}
return um
}

func (u *UserMap) getMap(key string) *sync.Map {
hash := fnv.New32a()
hash.Write([]byte(key))
index := hash.Sum32() % uint32(len(u.maps))
return &u.maps[index]
}

func (u *UserMap) GetAll(key string) ([]*Client, bool) {
allClients, ok := u.m.Load(key)
sm := u.getMap(key)
allClients, ok := sm.Load(key)
if ok {
return allClients.([]*Client), ok
}
return nil, ok
}

func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) {
allClients, userExisted := u.m.Load(key)
sm := u.getMap(key)
allClients, userExisted := sm.Load(key)
if userExisted {
var clients []*Client
for _, client := range allClients.([]*Client) {
Expand All @@ -56,22 +69,24 @@ func (u *UserMap) Get(key string, platformID int) ([]*Client, bool, bool) {
}

func (u *UserMap) Set(key string, v *Client) {
allClients, existed := u.m.Load(key)
sm := u.getMap(key)
allClients, existed := sm.Load(key)
if existed {
log.ZDebug(context.Background(), "Set existed", "user_id", key, "client", *v)

Check failure on line 75 in internal/msggateway/user_map.go

View workflow job for this annotation

GitHub Actions / lint

copylocks: call of log.ZDebug copies lock value: github.com/openimsdk/open-im-server/v3/internal/msggateway.Client contains sync/atomic.Bool contains sync/atomic.noCopy (govet)
oldClients := allClients.([]*Client)
oldClients = append(oldClients, v)
u.m.Store(key, oldClients)
sm.Store(key, oldClients)
} else {
log.ZDebug(context.Background(), "Set not existed", "user_id", key, "client", *v)

Check failure on line 80 in internal/msggateway/user_map.go

View workflow job for this annotation

GitHub Actions / lint

copylocks: call of log.ZDebug copies lock value: github.com/openimsdk/open-im-server/v3/internal/msggateway.Client contains sync/atomic.Bool contains sync/atomic.noCopy (govet)
var clients []*Client
clients = append(clients, v)
u.m.Store(key, clients)
sm.Store(key, clients)
}
}

func (u *UserMap) delete(key string, connRemoteAddr string) (isDeleteUser bool) {
allClients, existed := u.m.Load(key)
sm := u.getMap(key)
allClients, existed := sm.Load(key)
if existed {
oldClients := allClients.([]*Client)
var a []*Client
Expand All @@ -81,21 +96,22 @@ func (u *UserMap) delete(key string, connRemoteAddr string) (isDeleteUser bool)
}
}
if len(a) == 0 {
u.m.Delete(key)
sm.Delete(key)
return true
} else {
u.m.Store(key, a)
sm.Store(key, a)
return false
}
}
return existed
}

func (u *UserMap) deleteClients(key string, clients []*Client) (isDeleteUser bool) {
sm := u.getMap(key)
m := utils.SliceToMapAny(clients, func(c *Client) (string, struct{}) {
return c.ctx.GetRemoteAddr(), struct{}{}
})
allClients, existed := u.m.Load(key)
allClients, existed := sm.Load(key)
if existed {
oldClients := allClients.([]*Client)
var a []*Client
Expand All @@ -105,16 +121,17 @@ func (u *UserMap) deleteClients(key string, clients []*Client) (isDeleteUser boo
}
}
if len(a) == 0 {
u.m.Delete(key)
sm.Delete(key)
return true
} else {
u.m.Store(key, a)
sm.Store(key, a)
return false
}
}
return existed
}

func (u *UserMap) DeleteAll(key string) {
u.m.Delete(key)
sm := u.getMap(key)
sm.Delete(key)
}

0 comments on commit d958056

Please sign in to comment.