Documentation ¶
Overview ¶
Package lock provides implementations for cancellable and distributed locks.
Example ¶
service, err := New("local:") if err != nil { panic(err) } cfg := &SessionConfig{TTL: time.Second * 10} id := "mylock" counter := 0 niter := 1000 wg := &sync.WaitGroup{} wg.Add(niter) for i := 0; i < niter; i++ { go func() { session, err := service.NewSession(cfg) if err != nil { panic(err) } lock := session.NewLocker(id) cancel, err := lock.Lock() if err != nil { panic(err) } select { case <-cancel: panic("lost lock") default: counter++ } err = lock.Unlock() if err != nil { panic(err) } wg.Done() }() } wg.Wait() fmt.Println(counter)
Output: 1000
Index ¶
Examples ¶
Constants ¶
const ( // ServiceEtcd stands for service name. ServiceEtcd = "etcd" // DefaultDialTimeoutEtcd is the timeout for failing to establish a connection. DefaultDialTimeoutEtcd = 3 * time.Second )
const ServiceLocal = "local"
Variables ¶
var ( ErrUnsupportedService = errors.NewKind("unsupported service: %s") ErrInvalidConnectionString = errors.NewKind("invalid connection string: %s") ErrCanceled = errors.NewKind("context canceled") ErrAlreadyClosed = errors.NewKind("already closed") )
var Services map[string]func(string) (Service, error)
Services is a registry of all supported services by name. Map key is the service name, which will be looked up in URIs scheme.
Functions ¶
This section is empty.
Types ¶
type Locker ¶
type Locker interface { // Context can be used to cancel the operation (e.g. with a timeout). // If it succeeds, it returns a cancel channel. Otherwise, it returns an // error. The cancel channel is closed whenever the lock is not held anymore. // Note that the lock might be lost before calling to Unlock. Lock() (<-chan struct{}, error) // Unlock releases the lock. It might return an error if the lock could not // be released cleanly. However, this error is merely informative and no // action needs to be taken. Locking services must ensure that a lock that // failed to be released cleanly expires at some point (e.g. after session // TTL expires). Unlock() error }
Locker is the interface to a lock.
type Service ¶
type Service interface { // NewSession creates a new locking session with the given configuration. // An error is returned if the session cannot be created (e.g. invalid // configuration, connection cannot be established to remote service). NewSession(*SessionConfig) (Session, error) // Close closes the service and releases any resources held by it. // If it is called more than once, ErrAlreadyClosed is returned. Close() error }
Service is a locking service.
func NewEtcd ¶
NewEtcd creates a new locking service based on etcd given a connection string. The connection string has the following form:
etcd:<endpoints>[?<opt1>=<val1>&<opt2>=<val2>]
For example:
etcd:http//foo:8888,http://bar:9999?dial-timeout=2s&reject-old-cluster=true
Valid options are:
- auto-sync-interval (time duration)
- dial-timeout (time duration)
- dial-keep-alive-time (time duration)
- dial-keep-alive-timeout (time duration)
- username (string)
- password (string)
- reject-old-cluster (boolean)
For further information about each option, check the etcd godocs at: https://godoc.org/github.com/coreos/etcd/clientv3#Config
type Session ¶
type Session interface { // NewService creates a NewService for the given id. Lockers returned for the // same id on different sessions are mutually exclusive. NewLocker(id string) Locker // Close closes the session and releases any resources held by it. // If it is called more than once, ErrAlreadyClosed is returned. Close() error // Done notifies the client when the session is finished. Done() <-chan struct{} }
Session is a locking session that can be reused to get multiple locks. Multiple actors should use different sessions.
type SessionConfig ¶
type SessionConfig struct { // Timeout is the timeout when acquiring a lock. Calls to Lock() on a Locker // in the session will fail if the lock cannot be acquired before timeout. Timeout time.Duration // TTL is the time-to-live of all locks in a session. A lock operation times // out when the TTL expires. A lock is lost whenever it cannot be kept alive // inside the TTL. For example, a lock in a distributed lock service maintains // a keep alive heartbeat, once a heartbeat is not received for more than // the specified TTL, it must be assumed that the lock is no longer held. TTL time.Duration }
SessionConfig holds configuration for a locking session.