lease

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

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

Go to latest
Published: Feb 17, 2022 License: Apache-2.0 Imports: 7 Imported by: 0

README

Lease

Lease is a general DynamoDB-based lease implementation, ideal for long-lived work items, with coarse-grained leases.

Usage

Firstly, we need to initialize a lock store that wraps DynamoDB:

// get the aws Config and DynamoDB instance however you like...
config := &aws.Config{
	Region: aws.String("us-east-1")}
ddb := dynamodb.New(config)

// create a new store, specifying the table and hash key
locker := lease.NewLockStore(ddb, "lock_table_name", "LockHashKeyName")

Then, we need to implement the LeaseRequest interface. We do this so we can give the locker an identifier so it knows who's leasing what.


type exampleLeaseRequest struct {
	processID string
}

// we only want one lease per process, so using the hostname:process_id,
func (er *exampleLeaseRequest) LesseeID() string {
	return er.processID
}

// take out a lease for 30 seconds
func (er *exampleLeaseRequest) LeaseDuration() time.Duration {
	return time.Second * 30
}

We can use this lease request to scan over all available items to lease until we get one:

// returns an error if we fail to get a lease
lease, err := locker.ObtainLease(&exampleLeaseRequest{processID: "132123"})

// or we can block until we get a lease
lease := locker.WaitUntilLeaseObtained(&exampleLeaseRequest{processID: "132123"}, time.Second * 15)

Finally we can tell the locker to heartbeat to keep renewing a lease:

go locker.Heartbeat(lease, time.Second * 15)
Testing

go test ./...

or with integration tests that require a real DynamoDB to connect to:

LEASETESTTABLENAME=ddb_table_name LEASETESTHASHKEY=hash_key go test ./... -tags=integration

Logging

Implement and set a logger conforming to the small LeaseLogger interface. Do this prior to use if you want logging to go anywhere. By default the library will work but you won't get any log messages.

lease.SetLogger(myLogger)

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	GlobalLockStore *LockStore

	// LeaseNotObtainedError returned when lease not obtained
	LeaseNotObtainedError error = errors.New("Lease Not Obtained")
)
View Source
var (
	// LeaseLostError returned when a lease is lost
	LeaseLostError error = errors.New("Lease Lost")
)

Functions

func SetLogger

func SetLogger(logger LeaseLogger)

Set the logger implementation used within Lease

func SetupLockStoreGlobal

func SetupLockStoreGlobal(ddb *dynamodb.DynamoDB, lockTableName, lockHashKeyName string)

SetupLockStoreGlobal initializes a global LockStore. Requires an instance of DynamoDB, a table name, and the name of the hash key for lock items.

Types

type Lease

type Lease struct {
	// LeaseID - HashKey value of the lease row
	LeaseID string
	// AttributeValues - Extra AttributeValues from the lease row
	AttributeValues map[string]*dynamodb.AttributeValue
	// Request - Lease Request that resulted in the Lease
	Request LeaseRequest
	// Until - Time the lease expires
	Until time.Time
}

A Lease represents a lease for a given ID

type LeaseLogger

type LeaseLogger interface {
	LogInfoMessage(message string, keyvals ...interface{})
	LogErrorMessage(message string, keyvals ...interface{})
}

LeaseLogger is the interface for the internal logger.

type LeaseRequest

type LeaseRequest interface {
	// LesseeID - A unique ID for the Lessee, so the lock is held for a single Lessee.
	LesseeID() string
	// LeaseDuration - How long to initially take out a lease for.
	LeaseDuration() time.Duration
}

A LeaseRequest represents a request for a Lease.

type LockStore

type LockStore struct {
	*dynamodb.DynamoDB
	// contains filtered or unexported fields
}

LockStore is the lockerStore implementation for DynamoDB.

func NewLockStore

func NewLockStore(ddb *dynamodb.DynamoDB, lockTableName, lockHashKeyName string) *LockStore

Returns a new LockStore. Requires an instance of DynamoDB, a table name, and the name of the hash key for lock items.

func (*LockStore) Lease

func (s *LockStore) Lease(leaseID string, request LeaseRequest, until time.Time) (*Lease, error)

Attempt to acquire, or renew, a lease on the given leaseID.

Returns a Lease if successfully acquired/renewed; if the lease is currently held by someone else, returns a LeaseNotObtainedError and nil Lease.

func (*LockStore) ListLeaseIDs

func (s *LockStore) ListLeaseIDs() ([]string, error)

List the IDs of all lease items stored in DynamoDB.

Returns a list of string PKs of Lease's; returns errors if failing to contact Dynamo.

type Locker

type Locker struct {
	// contains filtered or unexported fields
}

A Locker provides methods to obtain and renew leases.

func NewLocker

func NewLocker(store lockerStore) *Locker

Initialization of a Locker, requires a lockerStore.

func (*Locker) Heartbeat

func (l *Locker) Heartbeat(lease *Lease, heartbeatDuration time.Duration) error

Heartbeat starts a loop that renews the lease periodically. Returns LeaseLostError if the lease is lost Returns other errors when failing to contact DDB.

func (*Locker) ObtainLease

func (l *Locker) ObtainLease(request LeaseRequest) (*Lease, error)

ObtainLease scans over possible leaseable items and tries to acquire a lease on any of them. Returns nil with a LeaseNotObtainedError if it can't acquire a lease.

func (*Locker) WaitUntilLeaseObtained

func (l *Locker) WaitUntilLeaseObtained(request LeaseRequest, waitPeriod time.Duration) *Lease

WaitUntilLeaseObtained scans over possible leaseable items and tries to acquire a lease on any of them. Returns as soon as it acquires a lease on one.

Keeps trying indefinitely until it acquires a lease, waiting waitPeriod between scans of the table.

Jump to

Keyboard shortcuts

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