Documentation ¶
Index ¶
- Variables
- type Canceler
- type Group
- type LockManager
- type LockOption
- type LockSession
- type ManagedLock
- func (ml *ManagedLock) IsLocked() bool
- func (ml *ManagedLock) Key() string
- func (ml *ManagedLock) Lock(opts ...LockOption) *LockSession
- func (ml *ManagedLock) LockContext(context doneContext, opts ...LockOption) (*LockSession, error)
- func (ml *ManagedLock) LockTimeout(duration time.Duration, opts ...LockOption) (*LockSession, bool)
- func (ml *ManagedLock) TryLock(opts ...LockOption) (*LockSession, bool)
- func (ml *ManagedLock) Unlock()
- type MultiErrGroup
- type Mutex
- type SafeWaitGroup
- type TaskGroup
- type TxExclusiveLock
- type TxLock
- type TxPendingLock
- type TxReservedLock
- type TxSharedLock
- type WithSignalCallbacks
Constants ¶
This section is empty.
Variables ¶
var ErrGroupClosed = errors.New("group closed")
ErrGroupClosed indicates that the WaitGroup is currently closed, and no more routines can be started.
Functions ¶
This section is empty.
Types ¶
type Canceler ¶ added in v0.0.2
type Canceler interface { Done() <-chan struct{} Err() error }
Canceler interface, that can be used to pass along some shutdown signal to child goroutines.
type Group ¶ added in v0.0.2
type Group interface { // Go method returns an error if the task can not be started. The error // returned by the task itself is not supposed to be returned, as the error is // assumed to be generated asynchronously. Go(fn func(Canceler) error) error }
Group interface, that can be used to start tasks. The tasks started will spawn go-routines, and will get a shutdown signal by the provided Canceler.
func ClosedGroup ¶ added in v0.0.2
ClosedGroup creates a Group that always fails to start a go-routine. Go will return reportedError on each attempt to create a go routine. If reportedError is nil, ErrGroupClosed will be used.
type LockManager ¶
type LockManager struct {
// contains filtered or unexported fields
}
LockManager gives access to a set of Locks by name. The lock manager can forcefully unlock a lock. Routines using a managed lock can use the LockSession to list for special Lock events.
The zero value of LockManager is directly usable, but a LockManager must no be copied by value.
func NewLockManager ¶
func NewLockManager() *LockManager
NewLockManager creates a new LockManager instance.
func (*LockManager) Access ¶
func (m *LockManager) Access(key string) *ManagedLock
Access gives access to a ManagedLock. The ManagedLock MUST NOT be used by more than one go-routine. If 2 go-routines need to coordinate on a lock managed by the same LockManager, then 2 individual ManagedLock instances for the same key must be created.
func (*LockManager) ForceUnlock ¶
func (m *LockManager) ForceUnlock(key string)
ForceUnlock unlocks the ManagedLock that is currently holding the Lock. It is advised to listen on the LockSession.LockLost or LockSession.Done events.
func (*LockManager) ForceUnlockAll ¶
func (m *LockManager) ForceUnlockAll()
ForceUnlockAll force unlocks all current locks that are managed by this lock manager.
type LockOption ¶
type LockOption interface {
// contains filtered or unexported methods
}
LockOption is used to pass additonal settings to all LockX methods of the ManagedLock.
type LockSession ¶
type LockSession struct {
// contains filtered or unexported fields
}
LockSession provides signal with the current lock state. Lock sessions must not be reused, as each Lock operation returns a new Session object.
func (*LockSession) Done ¶
func (s *LockSession) Done() <-chan struct{}
Done returns a channel to wait for a final signal. The signal will become available if the session has been finished due to an Unlock or Forced Unlock.
func (*LockSession) LockLost ¶
func (s *LockSession) LockLost() <-chan struct{}
LockLost return a channel, that will signal that the ManagedLock has lost its lock status. When receiving this signal, ongoing operations should be cancelled, or results should be ignored, as other MangedLocks might be able to acquire the lock the moment the current session has lost the lock.
func (*LockSession) Unlocked ¶
func (s *LockSession) Unlocked() <-chan struct{}
Unlocked returns a channel, that will signal that the ManagedLock was unlocked. A ManagedLock can still be unlocked (which will trigger the signal), even after loosing the actual Lock.
type ManagedLock ¶
type ManagedLock struct {
// contains filtered or unexported fields
}
ManagedLock is a mutex like structure that is managed by the LockManager. A managed lock can loose it's lock lease at any time. The LockX methods return a LockSession that can be used to listen for the current Locks state changes.
The lock will automatically be released in case the ManagedLock is garbage collected. One should not rely on this behavior, but releaseing a zombie lock guarantees that other routines might eventually be able to make progress in case of fatal errors.
func (*ManagedLock) IsLocked ¶
func (ml *ManagedLock) IsLocked() bool
IsLocked checks if the resource currently holds the lock for the key
func (*ManagedLock) Key ¶
func (ml *ManagedLock) Key() string
Key reports the key the lock will lock/unlock.
func (*ManagedLock) Lock ¶
func (ml *ManagedLock) Lock(opts ...LockOption) *LockSession
Lock the key. It blocks until the lock becomes available. Lock returns a LockSession, which is valid until after Unlock is called.
Note: After loosing a lock, the ManagedLock must still call 'Unlock' in
order to be reusable.
func (*ManagedLock) LockContext ¶
func (ml *ManagedLock) LockContext(context doneContext, opts ...LockOption) (*LockSession, error)
LockContext tries to acquire the lock. The Log operation can be cancelled by the context. LockContext returns nil on success, otherwise the error value returned by context.Err, which MUST NOT return nil after cancellation.
On success a LockSession will be returned as well. The Lock session is valid until Unlock has been called.
func (*ManagedLock) LockTimeout ¶
func (ml *ManagedLock) LockTimeout(duration time.Duration, opts ...LockOption) (*LockSession, bool)
LockTimeout will try to acquire lock. A failed lock attempt returns false, once the amount of configured duration has been passed.
If duration is 0, then the call behaves like TryLock. If duration is <0, then the call behaves like Lock
On success a LockSession will be returned as well. The Lock session is valid until Unlock has been called.
func (*ManagedLock) TryLock ¶
func (ml *ManagedLock) TryLock(opts ...LockOption) (*LockSession, bool)
TryLock attempts to acquire the lock. If the lock is already held by another shared lock, then TryLock will return false.
On success a LockSession will be returned as well. The Lock session is valid until Unlock has been called.
type MultiErrGroup ¶ added in v0.0.2
type MultiErrGroup struct {
// contains filtered or unexported fields
}
MultiErrGroup is a collection of goroutines working on subtasks concurrently. The group waits until all subtasks have finished and collects all errors encountered.
The zero value of MultiErrGroup is a valid group.
func (*MultiErrGroup) Go ¶ added in v0.0.2
func (g *MultiErrGroup) Go(fn func() error)
Go starts a new go-routine, collecting errors encounted into the MultiErrGroup.
func (*MultiErrGroup) Wait ¶ added in v0.0.2
func (g *MultiErrGroup) Wait() []error
Wait waits until all go-routines have been stopped and returns all errors encountered.
type Mutex ¶
type Mutex struct {
// contains filtered or unexported fields
}
Mutex provides a mutex based on go channels. The lock operations support timeout or cancellation by a context. Moreover one can try to lock the mutex from within a select statement when using Await.
The zero value of Mutex will not be able to Lock the mutex ever. The Lock method will never return. Calling Unlock will panic.
func (Mutex) Await ¶
func (c Mutex) Await() <-chan struct{}
Await returns a channel that will be triggered if the lock attempt did succeed. One can use the channel with select-case. The mutex is assumed to be locked if the branch waiting on the mutex has been triggered.
func (Mutex) Lock ¶
func (c Mutex) Lock()
Lock blocks until the mutex has been acquired. The zero value of Mutex will block forever.
func (Mutex) LockContext ¶
LockContext tries to lock the mutex. The Log operation can be cancelled by the context. LockContext returns nil on success, otherwise the error value returned by context.Err, which MUST NOT return nil after cancellation.
func (Mutex) LockTimeout ¶
LockTimeout will try to lock the mutex. A failed lock attempt returns false, once the amount of configured duration has been passed.
If duration is 0, then the call behaves like TryLock. If duration is <0, then the call behaves like Lock if the Mutex has been initialized, otherwise fails.
The zero value of Mutex will never succeed.
type SafeWaitGroup ¶ added in v0.0.2
type SafeWaitGroup struct {
// contains filtered or unexported fields
}
SafeWaitGroup provides a safe alternative to WaitGroup, that instead of panicing returns an error when Wait has been called.
func (*SafeWaitGroup) Add ¶ added in v0.0.2
func (s *SafeWaitGroup) Add(n int) error
Add adds the delta to the WaitGroup counter. If the counter becomes 0, all goroutines are blocked on Wait will continue.
Add returns an error if 'Wait' has already been called, indicating that no more go-routines should be started.
func (*SafeWaitGroup) Close ¶ added in v0.0.2
func (s *SafeWaitGroup) Close()
Close marks the wait group as closed. All calls to Add will fail with ErrGroupClosed after close has been called. Close does not wait until the WaitGroup counter has reached zero, but will return immediately. Use Wait to wait for the counter to become 0.
func (*SafeWaitGroup) Done ¶ added in v0.0.2
func (s *SafeWaitGroup) Done()
Done decrements the WaitGroup counter.
func (*SafeWaitGroup) Wait ¶ added in v0.0.2
func (s *SafeWaitGroup) Wait()
Wait closes the WaitGroup and blocks until the WaitGroup counter is zero. Add will return errors the moment 'Wait' has been called.
type TaskGroup ¶ added in v0.0.2
type TaskGroup struct { // StopOnError configures the behavior when a sub-task failed. If not set // all other tasks will continue to run. If the function return true, a // shutdown signal is passed, and Go will fail on attempts to start new // tasks. StopOnError func(err error) bool // contains filtered or unexported fields }
TaskGroup implements the Group interface. Once the group is shutting down, no more goroutines can be created via Go. The Stop method of TaskGroup will block until all sub-tasks have returned. Errors from sub-tasks are collected. The Stop method collects all errors and returns a single error summarizing all errors encountered.
By default sub-tasks continue running if any task did encounter an error. This behavior can be modified by setting StopOnError.
The zero value of TaskGroup is fully functional. StopOnError must not be set after the first go-routine has been spawned.
type TxExclusiveLock ¶
type TxExclusiveLock TxLock
TxExclusiveLock is used by writers to wait for exclusive access to all resources. The writer should make changes visible to future readers only after acquiring the exclusive lock.
func (*TxExclusiveLock) Lock ¶
func (l *TxExclusiveLock) Lock()
Lock acquires the exclusive lock. Once acquired it is guaranteed that no other reader or writer go-routine exists.
func (*TxExclusiveLock) Unlock ¶
func (l *TxExclusiveLock) Unlock()
Unlock is a noop. It guarantees that TxExclusiveLock is compatible to sync.Locker.
type TxLock ¶
type TxLock struct {
// contains filtered or unexported fields
}
TxLock provides locking support for transactional updates with multiple concurrent readers and one writer. Unlike sync.RWLock, the writer and readers can coexist. Users of TxLock must ensure proper isolation, between writers/readers. Changes by the writer must not be accessible by readers yet. A writer should hold the exclusive lock before making the changes available to others.
Lock types:
- Shared: Shared locks are used by readonly loads. Multiple readers can co-exist with one active writer.
- Reserved: Writer use the reserved lock. Once locked no other writer can acquire the Reserved lock. The shared lock can still be locked by concurrent readers.
- Pending: The pending lock is used by the writer to signal a write is about to be committed. After acquiring the pending lock no new reader is allowed to acquire the shared lock. Readers will have to wait until the pending lock is released. Existing readers can still coexist, but no new reader is allowed.
- Exclusive: Once the exclusive lock is acquired by a write transaction, No other active transactions/locks exist anymore. Locking the exclusive lock blocks until the shared lock has been released by all readers.
Each Locktype can be accessed using `(*lock).<Type>()`. Each lock type implements a `Lock` and `Unlock` method.
The zero value of TxLock must not be used.
func (*TxLock) Exclusive ¶
func (l *TxLock) Exclusive() *TxExclusiveLock
Exclusive returns the files exclusive locker.
func (*TxLock) Pending ¶
func (l *TxLock) Pending() *TxPendingLock
Pending returns the files pending locker.
func (*TxLock) Reserved ¶
func (l *TxLock) Reserved() *TxReservedLock
Reserved returns the files reserved locker.
func (*TxLock) Shared ¶
func (l *TxLock) Shared() *TxSharedLock
Shared returns the files shared locker.
type TxPendingLock ¶
type TxPendingLock TxLock
TxPendingLock is used by writers to signal the TxLock that the shared lock can not be acquired anymore. Readers will unblock once Unlock on the pending lock is called.
func (*TxPendingLock) Lock ¶
func (l *TxPendingLock) Lock()
Lock acquires the pending lock. The reserved lock must be acquired before.
func (*TxPendingLock) Unlock ¶
func (l *TxPendingLock) Unlock()
Unlock releases the pending lock, potentially unblocking waiting readers.
type TxReservedLock ¶
type TxReservedLock TxLock
TxReservedLock is used by writers to lock the reserved lock on a TxLock. Only one go-routine is allowed to acquire the reserved lock at a time.
func (*TxReservedLock) Lock ¶
func (l *TxReservedLock) Lock()
Lock acquires the reserved lock. Only one go-routine can hold the reserved lock at a time. The reserved lock should only be acquire by writers. Writers must not acquire the shared lock.
func (*TxReservedLock) Unlock ¶
func (l *TxReservedLock) Unlock()
Unlock releases the reserved lock.
type TxSharedLock ¶
type TxSharedLock TxLock
TxSharedLock is used by readers to lock the shared lock on a TxLock.
func (*TxSharedLock) Lock ¶
func (l *TxSharedLock) Lock()
Lock locks the shared lock. It blocks as long as the pending lock is in use.
func (*TxSharedLock) Unlock ¶
func (l *TxSharedLock) Unlock()
Unlock unlocks the shared lock. Unlocking potentially unblocks a waiting exclusive lock.
type WithSignalCallbacks ¶
type WithSignalCallbacks struct { // Done is executed after the Unlocked or Lost event has been emitted. Done will never be executed twice, // even if both events get emitted. Done func() // Unlocked is called when the lock has been explicitely unlocked. Unlocked func() // Lost is called when the Lock was force unlocked by the LockManager. Lost func() }
WithSignalCallbacks is a LockOption that configures additional callbacks to be executed on lock session state changes. A LockSession is valid until the lock has been Unlocked. The callbacks are registered with the lock session, and will not be called anymore once the LockSession is finalized.