utils

package module
v0.0.0-...-de1d73e Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2015 License: Apache-2.0 Imports: 11 Imported by: 0

README

etcd-lock

master.go

  • Master election using etcd.
  • TTL is refreshed by the lockholder.
  • Master failure results in another node acquiring the lock and becoming master.
  • Sample usage below.

rwlock.go

  • Distributed read write lock implementation using etcd.
  • Implemented using CreateInOrder (queue).
  • Fairness ensured by not letting reads leapfrog writes.
  • Queue TTL protects against node failures after requesting a lock.
  • Lock TTL protects against node failures after acquiring a lock.

Sample usage

import ".../utils"

func someFunc() {
  // Create an etcd client and a lock.
  lock, err := utils.NewMaster(utils.NewEtcdRegistry(), "foo", "172.16.1.101", 30)

  // Start a go routine to process events.
  go processEvents(lock.EventsChan())

  // Start the attempt to acquire the lock.
  lock.Start()
}

func processEvents(eventsCh <-chan utils.MasterEvent) {
     for {
        select {
        case e := <-k.eventsCh:
            if e.Type == utils.MasterAdded {
               // Acquired the lock.
            } else if e.Type == utils.MasterDeleted {
               // Lost the lock.
            } else {
               // Lock ownership changed.
            }
        ...
        }
     }
}

Documentation

Index

Constants

View Source
const (
	EtcdErrorCodeNotFound     = 100
	EtcdErrorCodeIndexCleared = 401
)

Variables

View Source
var (
	ErrLockID        = errors.New("Can't get lock id")
	ErrLockExpired   = errors.New("Lock request expired")
	ErrLockReqLost   = errors.New("Lock request lost")
	ErrLockEnq       = errors.New("Error enqueuing lock request")
	ErrLockGet       = errors.New("Error reading lock queue")
	ErrLockDelete    = errors.New("Error deleting lock")
	ErrLockMarshal   = errors.New("Marshal error")
	ErrLockUnmarshal = errors.New("Unmarshal error")
)

Possible errors returned by Lock/Unlock.

View Source
var (
	EtcdErrorNotFound = &etcd.EtcdError{ErrorCode: EtcdErrorCodeNotFound}
)
View Source
var (

	// GetLockID returns identity of a lock requester.
	GetLockID = func() (string, error) {
		return lockID, nil
	}
)
View Source
var LockTypes = map[LockType]string{
	LockTypeRead:  "read-lock",
	LockTypeWrite: "write-lock",
}
View Source
var QTTL = flag.Uint64("queue-ttl", 30, "Timeout in seconds for a lock queue entry")

Functions

func IsEtcdEventIndexCleared

func IsEtcdEventIndexCleared(err error) bool

func IsEtcdNotFound

func IsEtcdNotFound(err error) bool

IsEtcdNotFound checks if the err is a not found error.

func IsEtcdWatchStoppedByUser

func IsEtcdWatchStoppedByUser(err error) bool

IsEtcdWatchStoppedByUser checks if err indicates watch stopped by user.

func RUnlock

func RUnlock(client Registry, name string, handle LockHandle) error

RUnlock is used to unlock a read lock.

func WUnlock

func WUnlock(client Registry, name string, handle LockHandle) error

WUnlock is used to unlock a write lock.

Types

type LockHandle

type LockHandle string

func RLock

func RLock(client Registry, name string, ttl uint64) (LockHandle, error)

RLock is a function to acquire a read lock.

Inputs: client - etcd client object. lockType - type of the lock, read or write. name - name of the lock. ttl - time needed to complete the work after acquiring lock. If the

lock is not released within this time by calling Unlock, it is
automatically released.

Outputs: LockHandle - lock handle to provide to UnLock. error - any etcd errors or ttl expiry.

func WLock

func WLock(client Registry, name string, ttl uint64) (LockHandle, error)

WLock is a function to acquire a write lock.

Inputs: client - etcd client object. lockType - type of the lock, read or write. name - name of the lock. ttl - time needed to complete the work after acquiring lock. If the

lock is not released within this time by calling Unlock, it is
automatically released.

Outputs: LockHandle - lock handle to provide to UnLock. error - any etcd errors or ttl expiry.

type LockState

type LockState struct {
	LockType string
	Id       string
}

LockState is used to track lock holders/requests for a given lock and is stored as the value in etcd.

type LockType

type LockType int

Lock types.

const (
	LockTypeRead LockType = iota
	LockTypeWrite
)

type MasterEvent

type MasterEvent struct {
	Type   MasterEventType // event type
	Master string          // identity of the lock holder
}

MasterEvent represents a single event sent on the events channel.

type MasterEventType

type MasterEventType int

Various event types for the events channel.

const (
	MasterAdded MasterEventType = iota // this node has the lock.
	MasterDeleted
	MasterModified
	MasterError
)

type MasterInterface

type MasterInterface interface {
	// Start the election and attempt to acquire the lock. If acquired, the
	// lock is refreshed periodically based on the ttl.
	Start()

	// Stops watching the lock. Closes the events channel.
	Stop()

	// Returns the event channel used by the etcd lock.
	EventsChan() <-chan MasterEvent

	// Method to get the current lockholder. Returns "" if free.
	GetHolder() string
}

Interface used by the etcd master lock clients.

func NewMaster

func NewMaster(client Registry, name string, id string,
	ttl uint64) (MasterInterface, error)

Method to create a new etcd lock.

type Registry

type Registry interface {
	// Add a new file with a random etcd-generated key under the given path
	AddChild(key string, value string, ttl uint64) (*etcd.Response, error)
	// Get gets the file or directory associated with the given key.
	// If the key points to a directory, files and directories under
	// it will be returned in sorted or unsorted order, depending on
	// the sort flag.
	// If recursive is set to false, contents under child directories
	// will not be returned.
	// If recursive is set to true, all the contents will be returned.
	Get(key string, sort, recursive bool) (*etcd.Response, error)
	// Set sets the given key to the given value.
	// It will create a new key value pair or replace the old one.
	// It will not replace a existing directory.
	Set(key string, value string, ttl uint64) (*etcd.Response, error)
	// Update updates the given key to the given value. It succeeds only if the given key
	// already exists.
	Update(key string, value string, ttl uint64) (*etcd.Response, error)
	// Create creates a file with the given value under the given key. It succeeds
	// only if the given key does not yet exist.
	Create(key string, value string, ttl uint64) (*etcd.Response, error)
	// CreateInOrder creates a file with a key that's guaranteed to be higher than other
	// keys in the given directory. It is useful for creating queues.
	CreateInOrder(dir string, value string, ttl uint64) (*etcd.Response, error)
	// CreateDir create a driectory. It succeeds only if the given key
	// does not yet exist.
	CreateDir(key string, ttl uint64) (*etcd.Response, error)
	// Compare and swap only if prevValue & prevIndex match
	CompareAndSwap(key string, value string, ttl uint64, prevValue string,
		prevIndex uint64) (*etcd.Response, error)
	// Delete deletes the given key.
	// When recursive set to false, if the key points to a
	// directory the method will fail.
	// When recursive set to true, if the key points to a file,
	// the file will be deleted; if the key points to a directory,
	// then everything under the directory (including all child directories)
	// will be deleted.
	Delete(key string, recursive bool) (*etcd.Response, error)
	// If recursive is set to true the watch returns the first change under the
	// given prefix since the given index.
	// If recursive is set to false the watch returns the first change to the
	// given key since the given index.
	// To watch for the latest change, set waitIndex = 0.
	// If a receiver channel is given, it will be a long-term watch. Watch will
	// block at the channel. After someone receives the channel, it will go on
	// to watch that prefix. If a stop channel is given, the client can close
	// long-term watch using the stop channel.
	Watch(prefix string, waitIndex uint64, recursive bool,
		receiver chan *etcd.Response, stop chan bool) (*etcd.Response, error)
}

Etcd client interface.

func NewEtcdRegistry

func NewEtcdRegistry() Registry

Jump to

Keyboard shortcuts

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