lock

package
v0.19.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 28, 2019 License: GPL-3.0 Imports: 11 Imported by: 6

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

View Source
const (
	// ServiceEtcd stands for service name.
	ServiceEtcd = "etcd"

	// DefaultDialTimeoutEtcd is the timeout for failing to establish a connection.
	DefaultDialTimeoutEtcd = 3 * time.Second
)
View Source
const ServiceLocal = "local"

Variables

View Source
var (
	ErrUnsupportedService      = errors.NewKind("unsupported service: %s")
	ErrInvalidConnectionString = errors.NewKind("invalid connection string: %s")
	ErrCanceled                = errors.NewKind("context canceled")
	ErrAlreadyClosed           = errors.NewKind("already closed")
)
View Source
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 New

func New(connstr string) (Service, error)

New creates a service given a connection string.

func NewEtcd

func NewEtcd(connstr string) (Service, error)

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

func NewLocal

func NewLocal() Service

NewLocal creates a new locking service that uses in-process locks. This can be used whenever locking is relevant only to the local process. Local locks are never lost, so TTL is ignored.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL