dplock

package
v1.8.0 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2021 License: MIT Imports: 9 Imported by: 1

Documentation

Index

Constants

View Source
const (
	DefaultTTL                           = 30
	DefaultPurgerPeriod                  = 5 * time.Minute
	DefaultAcquireMinPeriodMillis        = 20
	DefaultAcquireMaxPeriodMillis        = 50
	DefaultAcquireRetryTimeout           = 20 * time.Second
	DefaultUnlockMinPeriodMillis         = 5
	DefaultUnlockMaxPeriodMillis         = 10
	DefaultUnlockRetryTimeout            = 5 * time.Second
	DefaultTimeThresholdSinceLastRelease = 100 * time.Millisecond
	DefaultUsageSleep                    = 50 * time.Millisecond
	DefaultMaxCount                      = 10
)

Default config values

View Source
const AcquireRetryLogThreshold = 500 * time.Millisecond

AcquireRetryLogThreshold is the period of time after which an acquire retry will be logged

View Source
const MinAllowedPurgerPeriod = time.Second
View Source
const UnlockRetryLogThreshold = 100 * time.Millisecond

UnlockRetryLogThreshold is the period of time after which an unlock retry will be logged

Variables

View Source
var ErrAcquireTimeout = errors.New("cannot acquire lock, acquire retry timeout has expired")

ErrAcquireTimeout is an error returned when acquire fails after retrying to lock a resource for a period of time greater or equal than 'AcquireRetryTimeout'

View Source
var ErrMongoDbClosing = errors.New("mongo db is being closed")

ErrMongoDbClosing is an error returned because MongoDB is being closed

View Source
var ErrUnlockTimeout = errors.New("cannot unlock, unlock retry timeout has expired")

ErrUnlockTimeout is an error logged when unlock fails after retrying to unlock a resource for a period of time greater or equal than 'UnlockRetryTimeout'

View Source
var GenerateTimeID = func() int {
	return time.Now().Nanosecond()
}

GenerateTimeID returns the current timestamp in nanoseconds

View Source
var Sleep = func(d time.Duration) {
	time.Sleep(d)
}

Functions

This section is empty.

Types

type Client

type Client interface {
	XLock(resourceName, lockID string, ld lock.LockDetails) error
	Unlock(lockID string) ([]lock.LockStatus, error)
}

Client defines the lock Client methods from mongo-lock

type Config added in v1.8.0

type Config struct {
	TTL                           uint          // TTL is the 'time to live' for a lock in number of seconds, note that expred locks will be cleaned up by the purger (so the worst case scenario is that a lock is cleaned up after TTL + PurgerPeriod)
	PurgerPeriod                  time.Duration // PurgerPeriod is the time period between expired lock purges
	AcquireMinPeriodMillis        uint          // AcquireMinPeriod is the minimum time period between acquire lock retries [ms]
	AcquireMaxPeriodMillis        uint          // AcquireMinPeriod is the maximum time period between acquire lock retries [ms]
	AcquireRetryTimeout           time.Duration // AcquireRetryTimeout is the maximum time period that locking will be retried, after the first attempt has failed
	UnlockMinPeriodMillis         uint          // UnlockMinPeriod is the minimum time period between Unlock retries [ms]
	UnlockMaxPeriodMillis         uint          // UnlockMaxPeriod is the maximum time period between Unlock retries [ms]
	UnlockRetryTimeout            time.Duration // UnlockRetryTimeout is the maximum time period that unlocking will be retried, after the first attempt has failed
	TimeThresholdSinceLastRelease time.Duration // TimeThresholdSinceLastRelease is the maximum period of time since the last time a lock was released for which the 'usage' counter will be increased
	UsageSleep                    time.Duration // UsageSleep is the period of time a caller will sleep after a sequence of MaxCount acquire and releases for a particular lock within TimeThresholdSinceLastRelease between releases and acquires.
	MaxCount                      uint          // MaxCount is the number of consecutive times a lock is released and re-acquired within a TimeThresholdSinceLastRelease period, for which a sleep will be triggered in order to prevent the caller from monopolising the lock.
}

Config is a lock configuration

func GetConfig added in v1.8.0

func GetConfig(cfgOverride *ConfigOverride) Config

GetConfig returns a full config, containing any value provided by configOverrides, and the default values otherwise

func (*Config) Validate added in v1.8.0

func (c *Config) Validate() error

Validate checks that the config values will not result in any unexpected behavior

type ConfigOverride added in v1.8.0

type ConfigOverride struct {
	TTL                           *uint
	PurgerPeriod                  *time.Duration
	AcquireMinPeriodMillis        *uint
	AcquireMaxPeriodMillis        *uint
	AcquireRetryTimeout           *time.Duration
	UnlockMinPeriodMillis         *uint
	UnlockMaxPeriodMillis         *uint
	UnlockRetryTimeout            *time.Duration
	TimeThresholdSinceLastRelease *time.Duration
	UsageSleep                    *time.Duration
	MaxCount                      *uint
}

ConfigOverride is a config with pointer values, which are used to override values (it not nil)

type Lock

type Lock struct {
	Client        Client
	CloserChannel chan struct{}
	Purger        Purger
	WaitGroup     *sync.WaitGroup
	Resource      string
	Cfg           Config
	Usages        Usages
}

Lock is a MongoDB lock for a resource

func New

func New(ctx context.Context, session *mgo.Session, db, resource string, cfg *ConfigOverride) (*Lock, error)

New creates a new mongoDB lock for the provided session, db, collection and resource

func (*Lock) Acquire

func (l *Lock) Acquire(ctx context.Context, resourceID, uniqueCallerName string) (lockID string, err error)

Acquire tries to lock the provided resourceID. If the resource is already locked, this function will block until the existing lock is released, at which point we acquire the lock and return. - resourceID should be the mongo ID of the resource we want to lock (e.g. image, instance, ...) - uniqueCallerName must be a unique string representing a caller, e.g. http request traceID

func (*Lock) Close

func (l *Lock) Close(ctx context.Context)

Close closes the closer channel, and waits for the WaitGroup to finish.

func (*Lock) GetResourceName added in v1.8.0

func (l *Lock) GetResourceName(resourceID string) string

GetResourceName generates a resource name by using the lock Resource and the provided resourceID

func (*Lock) Init

func (l *Lock) Init(ctx context.Context, lockClient Client, lockPurger Purger, cfg *ConfigOverride) error

Init initialises a lock with the provided client, purger and config, and starts the purger loop

func (*Lock) Lock

func (l *Lock) Lock(resourceID, uniqueCallerName string) (lockID string, err error)

Lock acquires an exclusive mongoDB lock with the provided id, with the default TTL value. If the resource is already locked, an error will be returned. - resourceID should be the mongo ID of the resource we want to lock (e.g. image, instance, ...) - uniqueCallerName must be a unique string representing a caller, e.g. http request traceID

func (*Lock) Unlock

func (l *Lock) Unlock(lockID string)

Unlock releases an exclusive mongoDB lock for the provided id (if it exists) - lockID must be the value that was returned by a successful Acquire or Lock call.

type Purger

type Purger interface {
	Purge() ([]lock.LockStatus, error)
}

Purger defines the lock Purger methods from mongo-lock

type Usage added in v1.8.0

type Usage struct {
	Count    uint      // counter for the number of times that a lock has been acquired on the first attempt within a short period of time after being released
	Released time.Time // timestamp for the last time that a lock was released
}

Usage keeps track of locks that have been acquired by a particular caller and resource

type Usages added in v1.8.0

type Usages struct {
	UsagesMap map[string]map[string]*Usage
	// contains filtered or unexported fields
}

Usages is a 2D map to keep track of lock usages by resourceID and unique caller names

func NewUsages added in v1.8.0

func NewUsages(cfg *Config) Usages

NewUsages returns a new Usages struct with the provided config and a new map and mutex

func (Usages) Purge added in v1.8.0

func (u Usages) Purge()

Purge removes all the Usages that have expired (last release happened earlier than TimeThresholdSinceLastRelease ago) This method is executed inside the Usages mutex

func (Usages) Remove added in v1.8.0

func (u Usages) Remove(resourceID, uniqueCallerName string)

Remove deletes the Usage for the provided ResourceID and uniqueCallerName, if it exists. If the uniqueCallerName was the last one for a resourceID, that map will also be deleted. This method is executed inside the Usages mutex

func (Usages) SetCount added in v1.8.0

func (u Usages) SetCount(resourceID, uniqueCallerName string)

SetCount increases the counter if the lock has been previously released in the last 'timeThresholdSinceLastRelease' otherwise it resets the counter to 0 if the Usage did not exist in the map, it will be created. This method is executed inside the Usages mutex

func (Usages) SetReleased added in v1.8.0

func (u Usages) SetReleased(resourceID, uniqueCallerName string, releasedTime time.Time)

SetReleased sets the provided released timestamp for the Usage of the provided resource and lock. Only if the usage already exists in the map. This method is executed inside the Usages mutex

func (Usages) WaitIfNeeded added in v1.8.0

func (u Usages) WaitIfNeeded(resourceID, uniqueCallerName string)

WaitIfNeeded sleeps for 'usageSleep' time if the provided resource has been locked by the provided unique caller name at least MaxCount times, with a period of time smaller than 'timeThresholdSinceLastRelease' between releasing and re-acquiring the lock for all times. After sleeping, the counter is reset to 0 (if the usage was purged, it will be re-created) This method is executed inside the Usages mutex, except the Sleep

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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