Documentation
¶
Index ¶
- type EtcdRWLock
- func (*EtcdRWLock) IsCanceled(err error) bool
- func (lock *EtcdRWLock) Key() string
- func (lock *EtcdRWLock) RLock(ctx context.Context) error
- func (lock *EtcdRWLock) RUnlock(ctx context.Context) error
- func (lock *EtcdRWLock) RWLock(ctx context.Context) error
- func (lock *EtcdRWLock) RWUnlock(ctx context.Context) error
- type LocalLock
- func (lock *LocalLock) IsCanceled(err error) bool
- func (lock *LocalLock) Key() string
- func (lock *LocalLock) RLock(ctx context.Context) error
- func (lock *LocalLock) RUnlock(ctx context.Context) error
- func (lock *LocalLock) RWLock(ctx context.Context) error
- func (lock *LocalLock) RWUnlock(ctx context.Context) error
- type RWLock
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type EtcdRWLock ¶
type EtcdRWLock struct {
// contains filtered or unexported fields
}
EtcdRWLock is a custom implementation of a reader-writer writer-preference (often referred to as "problem 2") concurrent control strategy, based upon etcd distributed values and mutual exclusions (mutex).
For error management purposes, it does not use "defer" instructions thus any error is processed synchronously.
Current implementation expect the network to be reliable. Moreover, it is unqueued thus unfair, and does not repair in case of session rotation.
It tries its best to ensure each operation is atomic, by executing actions that can be recovered easily. Such is performed through the algorithm:
- Create a "stack" of previous P(x) for their corresponding V(x), and add V(x) iif x should be recoverable;
- If the V(x) is executed in the normal workflow, it is poped out of the "stack" as it is not longer needed to recover;
- If there is an error, execute all stack in LIFO order.
By doing so, we expect an operation to recover even if it is canceled by the requester. Note that it behave somewhat similar to sagas-based recovery, but not using them is simpler to model in our case. TODO make counters recoverable too to avoid deadlocks.
Original implementation based upon 'Concurrent Control with "Readers" and "Writers"' by Courtois et al. (1971) (DOI: 10.1145/362759.362813). Implementations decisions with etcd in the context of distributed systems goes to CTFer.io.
func (*EtcdRWLock) IsCanceled ¶ added in v0.6.2
func (*EtcdRWLock) IsCanceled(err error) bool
func (*EtcdRWLock) Key ¶
func (lock *EtcdRWLock) Key() string
type LocalLock ¶
type LocalLock struct {
// contains filtered or unexported fields
}
func (*LocalLock) IsCanceled ¶ added in v0.6.2
type RWLock ¶
type RWLock interface {
// Key of the lock
Key() string
// IsCancel is a helper that checks whether the given error is due to a context cancelation.
IsCanceled(error) bool
// RLock is a reader lock
RLock(context.Context) error
// RUnlock is a reader unlock
RUnlock(context.Context) error
// RWLock is a writer lock, thus as priority over readers
RWLock(context.Context) error
// RWUnlock is a writer unlock
RWUnlock(context.Context) error
}
RWLock define an implementation of a readers-writer lock with writer-preference.
Locks should be short-lived and recover from previous states without the need to persist them in memory (for fault-tolerancy and scalability). This imply the context should be passed to the constructor rather than methods.