twitch-bot/internal/locker/locker.go
Knut Ahlers 5dd6a5323c
[core] Add locking to prevent concurrent rule executions
refs #59

ensures counter actions are not triggered concurrently by two persons

Signed-off-by: Knut Ahlers <knut@ahlers.me>
2024-05-01 22:39:18 +02:00

51 lines
1.2 KiB
Go

// Package locker contains a way to interact with arbitrary locks
package locker
import "sync"
var (
locks = map[string]*sync.RWMutex{}
locksOLocks sync.RWMutex
)
// LockByKey takes a key to lock and locks the corresponding RWMutex
func LockByKey(key string) { getLockByKey(key).Lock() }
// RLockByKey takes a key to lock and read-locks the corresponding RWMutex
func RLockByKey(key string) { getLockByKey(key).RLock() }
// RUnlockByKey takes a key to lock and read-unlocks the corresponding RWMutex
func RUnlockByKey(key string) { getLockByKey(key).RUnlock() }
// UnlockByKey takes a key to lock and unlocks the corresponding RWMutex
func UnlockByKey(key string) { getLockByKey(key).Unlock() }
// WithLock takes a key to lock and a function to execute during the
// lock of this key
func WithLock(key string, fn func()) {
LockByKey(key)
defer UnlockByKey(key)
fn()
}
// WithRLock takes a key to lock and a function to execute during the
// read-lock of this key
func WithRLock(key string, fn func()) {
RLockByKey(key)
defer RUnlockByKey(key)
fn()
}
func getLockByKey(key string) *sync.RWMutex {
locksOLocks.Lock()
defer locksOLocks.Unlock()
if locks[key] == nil {
locks[key] = new(sync.RWMutex)
}
return locks[key]
}