Documentation ¶
Index ¶
- type Lockable
- func (l Lockable[T]) IsLocked(key T) bool
- func (l Lockable[T]) LockKey(key T)
- func (l Lockable[T]) LockKeyDuring(key T, fn func() (any, error)) (any, error)
- func (l Lockable[T]) RLockKey(key T)
- func (l Lockable[T]) RLockKeyDuring(key T, fn func() (any, error)) (any, error)
- func (l Lockable[T]) RUnlockKey(key T)
- func (l Lockable[T]) UnlockKey(key T)
- type Map
- type MutexMap
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Lockable ¶
type Lockable[T comparable] struct { // contains filtered or unexported fields }
Lockable can be used to add lock-by-key support to any struct.
The zero value is not ready for use. Refer to New for creating ready-to-use instance.
Lockable has an interface that's deliberately similar to sync.RWMutex.
For exemple, instead of using:
func main() { // Read/write lock myMutex.Lock() defer myMutex.Unlock() // Read lock myMutex.RLock() defer myMutex.RUnlock() }
You would use it like so:
func main() { // Read/write lock myLockable.LockKey(arbitraryKey) defer myLockable.Unlock(arbitraryKey) // Read lock myLockable.RLock(arbitraryKey) defer myLockable.RUnlock(arbitraryKey) }
You can use it to add lock-by-key support to an already existing struct.
Ex.:
func main() { type ArbitraryType struct { lockable.Lockable[string] // properties... } arbitrary := ArbitraryType{ Lockable: lockable.New[string](), } // You can now use it the way to acquire locks arbitrary.LockKey("potato") defer arbitrary.UnlockKey("potato") // Do stuff... }
Lockable.LockKeyDuring and Lockable.RLockKeyDuring can be used to automatically manage lock acquisition/release.
Ex.:
func main() { type ArbitraryType struct { lockable.Lockable[string] // properties... } arbitrary := ArbitraryType{ Lockable: lockable.New[string](), } _, err := arbitrary.LockKeyDuring("potato", func() (any, error) { // Do stuff... }) }
You can use Lockable.IsLocked to check if a lock is currently being held without locking the key. Ex.:
func main() { type ArbitraryType struct { lockable.Lockable[string] // properties... } arbitrary := ArbitraryType{ Lockable: lockable.New[string](), } if arbitrary.IsLocked("potato") { //.. do stuff. } }
func New ¶ added in v0.2.0
func New[T comparable]() Lockable[T]
New creates a ready-to-use Lockable instance.
Refer to Lockable for usage
func (Lockable[T]) IsLocked ¶ added in v0.2.0
IsLocked is used to determine whether a key has been locked without locking the key.
func (Lockable[T]) LockKey ¶
func (l Lockable[T]) LockKey(key T)
LockKey method is used to acquire read/write locks.
Use Lockable.RLockKey for read locks.
func (Lockable[T]) LockKeyDuring ¶
LockKeyDuring will automatically acquire a read/write lock before executing fn and release it once done.
func (Lockable[T]) RLockKey ¶
func (l Lockable[T]) RLockKey(key T)
RLockKey method is used to acquire read locks.
Use Lockable.RLockKey for read/write locks.
func (Lockable[T]) RLockKeyDuring ¶
RLockKeyDuring before executing fn and release it once done.
func (Lockable[T]) RUnlockKey ¶
func (l Lockable[T]) RUnlockKey(key T)
RUnlockKey method is used to release read/write locks.
Can safely be called multiple times on the same key.
type Map ¶
type Map[T comparable, V any] struct { Lockable[T] // contains filtered or unexported fields }
Map implements a map that can acquire key-specific locks.
The zero value is not ready for use. Refer to NewMap to create a ready-to-use instance.
Map has an interface that's deliberately similar to sync.Map, but uses a combination of RWMutex/map to simulate it.
MutexMap can be used instead if you want to use sync.Map internally. Refer to sync.Map's document for use cases.
Ex. usage:
func main() { lockableMap := lockable.NewMap[string, int]() // This will only lock access the "potato" key // Keys do not need to exist prior to acquiring the key lock lockableMap.LockKey("potato") defer lockableMap.UnlockKey("potato") // Do async stuff.... lockableMap.Store("potato", 10) }
Refer to Lockable for more detailed exemples of locking.
func NewMap ¶
func NewMap[T comparable, V any]() Map[T, V]
NewMap creates a ready-to-use Map instance.
Refer to Map for usage.
func (Map[T, V]) Delete ¶
func (m Map[T, V]) Delete(key T)
Delete effectively serves the same purpose as sync.Map.Delete
func (Map[T, V]) Load ¶
Load effectively serves the same purpose as sync.Map.Load
func (Map[T, V]) Range ¶
Range effectively serves the same purpose as sync.Map.Range
func (Map[T, V]) Store ¶
func (m Map[T, V]) Store(key T, value V)
Store effectively serves the same purpose as sync.Map.Store
type MutexMap ¶
type MutexMap[T comparable] struct { sync.Map Lockable[T] }
MutexMap acts the same as Map except it uses a sync.Map.
The zero value is not ready for use. Refer to NewMutexMap to create a ready-to-use instance.
Ex. usage: func main() { lockableMap := lockable.NewMutexMap[string]() // This will only lock access the "potato" key // Keys do not need to exist prior to acquiring the key lock lockableMap.LockKey("potato") defer lockableMap.UnlockKey("potato") // Do async stuff.... lockableMap.Store("potato", 10) }
Refer to Lockable for more detailed exemples of locking
func NewMutexMap ¶
func NewMutexMap[T comparable]() MutexMap[T]
NewMutexMap creates a ready-to-use MutexMap instance.
Refer to MutexMap for usage.