@@ -23,6 +23,8 @@ import (
2323 "sync"
2424 "time"
2525
26+ "k8s.io/utils/keymutex"
27+
2628 pkggc "d7y.io/dragonfly/v2/pkg/gc"
2729 "d7y.io/dragonfly/v2/scheduler/config"
2830)
@@ -32,6 +34,9 @@ const (
3234 GCPeerID = "peer"
3335)
3436
37+ // peerMutexShardCount is the number of mutex shards for peer mutations.
38+ const peerMutexShardCount = 256
39+
3540// PeerManager is the interface used for peer manager.
3641type PeerManager interface {
3742 // Load returns peer for a key.
@@ -73,8 +78,8 @@ type peerManager struct {
7378 // pieceDownloadTimeout is timeout of downloading piece.
7479 pieceDownloadTimeout time.Duration
7580
76- // mu is peer mutex.
77- mu * sync. Mutex
81+ // mu is a mutex for peer mutations .
82+ mu keymutex. KeyMutex
7883}
7984
8085// New peer manager interface.
@@ -84,7 +89,7 @@ func newPeerManager(cfg *config.GCConfig, gc pkggc.GC) (PeerManager, error) {
8489 peerTTL : cfg .PeerTTL ,
8590 hostTTL : cfg .HostTTL ,
8691 pieceDownloadTimeout : cfg .PieceDownloadTimeout ,
87- mu : & sync. Mutex {} ,
92+ mu : keymutex . NewHashed ( peerMutexShardCount ) ,
8893 }
8994
9095 if err := gc .Add (pkggc.Task {
@@ -111,8 +116,8 @@ func (p *peerManager) Load(key string) (*Peer, bool) {
111116
112117// Store sets peer.
113118func (p * peerManager ) Store (peer * Peer ) {
114- p .mu .Lock ( )
115- defer p .mu .Unlock ()
119+ p .mu .LockKey ( peer . ID )
120+ defer p .mu .UnlockKey ( peer . ID ) // nolint: errcheck
116121
117122 p .Map .Store (peer .ID , peer )
118123 peer .Task .StorePeer (peer )
@@ -123,8 +128,8 @@ func (p *peerManager) Store(peer *Peer) {
123128// Otherwise, it stores and returns the given peer.
124129// The loaded result is true if the peer was loaded, false if stored.
125130func (p * peerManager ) LoadOrStore (peer * Peer ) (* Peer , bool ) {
126- p .mu .Lock ( )
127- defer p .mu .Unlock ()
131+ p .mu .LockKey ( peer . ID )
132+ defer p .mu .UnlockKey ( peer . ID ) // nolint: errcheck
128133
129134 rawPeer , loaded := p .Map .LoadOrStore (peer .ID , peer )
130135 if ! loaded {
@@ -137,8 +142,8 @@ func (p *peerManager) LoadOrStore(peer *Peer) (*Peer, bool) {
137142
138143// Delete deletes peer for a key.
139144func (p * peerManager ) Delete (key string ) {
140- p .mu .Lock ( )
141- defer p .mu .Unlock ()
145+ p .mu .LockKey ( key )
146+ defer p .mu .UnlockKey ( key ) // nolint: errcheck
142147
143148 if peer , loaded := p .Load (key ); loaded {
144149 p .Map .Delete (key )
0 commit comments