-
Notifications
You must be signed in to change notification settings - Fork 16
/
locker.go
36 lines (30 loc) · 1.06 KB
/
locker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package sarah
import (
"fmt"
"sync"
)
var configLocker = &configRWLocker{
pluginMutex: map[string]*sync.RWMutex{},
mutex: sync.Mutex{},
}
// configRWLocker provides a locking mechanism for Command/ScheduledTask to safely read and write the config struct in a concurrent manner.
// This was introduced to solve a race condition caused by concurrent live re-configuration and Command/ScheduledTask execution.
// Detailed description can be found at https://github.com/oklahomer/go-sarah/issues/44.
//
// Mutex instance is created and managed per Command/ScheduledTask ID because some may share the same identifier
// and hence may refer to the same resource.
type configRWLocker struct {
pluginMutex map[string]*sync.RWMutex
mutex sync.Mutex
}
func (cl *configRWLocker) get(botType BotType, pluginID string) *sync.RWMutex {
cl.mutex.Lock()
defer cl.mutex.Unlock()
lockID := fmt.Sprintf("botType:%s::id:%s", botType.String(), pluginID)
locker, ok := cl.pluginMutex[lockID]
if !ok {
locker = &sync.RWMutex{}
cl.pluginMutex[lockID] = locker
}
return locker
}