Documentation ¶
Overview ¶
Package lock provides lock contention diagnostics for go mutexes.
This package provides a write-only mutex as well as a read and write mutex that can be swapped for the mutexes in the sync package. They extend the sync package by tracking the caller when they request a lock or unlock.
If lock contention is experienced in such a way that the program doesn't panic (primarily when there are many go routines all making progress in different parts of the program), you can print a report of which callers are attempting to acquire locks, and which callers have not released their locks yet, helping to diagnose contention issues.
Index ¶
Examples ¶
Constants ¶
const UnknownCaller = "unknown caller"
UnknownCaller is used as the default caller if we cannot query it.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type MutexD ¶
MutexD wraps sync.Mutex to provide tracking for methods that call the lock object. Use the same way you would use a Mutex!
Example ¶
l := new(Lockable) go l.Alpha() time.Sleep(10 * time.Millisecond) for i := 0; i < 2; i++ { go l.Bravo() } fmt.Println(l.MutexD.String())
Output: 1 locks requested by github.com/bbengfort/x/lock.(*Lockable).Alpha 2 locks requested by github.com/bbengfort/x/lock.(*Lockable).Bravo
func (*MutexD) Init ¶
func (l *MutexD) Init()
Init the lock and internal data structures like the map. No need to Init() manually though as the lock methods do a check to ensure that it's ready.
func (*MutexD) Lock ¶
func (l *MutexD) Lock()
Lock the data structure, blocking all other calls that are requesting a lock until unlock is called. This method provides diagnostic information by recording the caller of the lock in an internal map. You can print a report to see who is attempting to acquire a lock and who is still holding any locks in the system.
func (*MutexD) String ¶
String returns a report about who is attempting to acquire locks and which callers currently hold locks. E.g. if more than one lock is in the lock map than the first one is holding the lock and the others are awaiting it.
func (*MutexD) Unlock ¶
func (l *MutexD) Unlock()
Unlock the data structure, allowing any other blocked calls that have requested a lock to acquire it. This method removes the caller from the internal map so it's easy to see who still is attempting to acquire locks and who has released them (or hasn't released them yet).
type RWMutexD ¶
RWMutexD wraps a sync.RWMutex to provide tracking for methods that call the lock object. Use the same way you would use a mutex in order to diagnose requested read locks, write locks, and currently held read and write locks.
Example ¶
l := new(RWLockable) go l.Alpha() time.Sleep(100 * time.Millisecond) for i := 0; i < 2; i++ { go l.Bravo() } fmt.Println(l.RWMutexD.String())
Output: 1 locks requested by github.com/bbengfort/x/lock.(*Lockable).Alpha 2 read locks requested by github.com/bbengfort/x/lock.(*Lockable).Bravo
func (*RWMutexD) Init ¶
func (l *RWMutexD) Init()
Init the lock and internal data structures like the maps. No need to call Init() manually, though, as the lock methods do a check beforehand.
func (*RWMutexD) Lock ¶
func (l *RWMutexD) Lock()
Lock the data structure, blocking all other calls that are requesting a lock until unlock is called. This method provides diagnostic information by recording the caller of the lock in an internal map. You can print a report to see who is attempting to acquire a lock and who is still holding any locks in the system.
func (*RWMutexD) RLock ¶
func (l *RWMutexD) RLock()
RLock the data structure, blocking all other calls that are requesting a lock until unlock is called. This method provides diagnostic information by recording the caller of the lock in an internal map. You can print a report to see who is attempting to acquire a lock and who is still holding any locks in the system.
func (*RWMutexD) RUnlock ¶
func (l *RWMutexD) RUnlock()
RUnlock the data structure, allowing any other blocked calls that have requested a lock to acquire it. This method removes the caller from the internal map so it's easy to see who still is attempting to acquire locks and who has released them (or hasn't released them yet).
func (*RWMutexD) String ¶
String returns a report about who is attempting to acquire locks and which callers currently hold locks. E.g. if more than one lock is in the lock map than the first one is holding the lock and the others are awaiting it.
func (*RWMutexD) Unlock ¶
func (l *RWMutexD) Unlock()
Unlock the data structure, allowing any other blocked calls that have requested a lock to acquire it. This method removes the caller from the internal map so it's easy to see who still is attempting to acquire locks and who has released them (or hasn't released them yet).