Documentation ¶
Index ¶
- Constants
- Variables
- type Client
- type Config
- type ConfigOverride
- type Lock
- func (l *Lock) Acquire(ctx context.Context, resourceID, uniqueCallerName string) (lockID string, err error)
- func (l *Lock) Close(ctx context.Context)
- func (l *Lock) GetResourceName(resourceID string) string
- func (l *Lock) Init(ctx context.Context, lockClient Client, lockPurger Purger, cfg *ConfigOverride) error
- func (l *Lock) Lock(resourceID, uniqueCallerName string) (lockID string, err error)
- func (l *Lock) Unlock(lockID string)
- type Purger
- type Usage
- type Usages
- func (u Usages) Purge()
- func (u Usages) Remove(resourceID, uniqueCallerName string)
- func (u Usages) SetCount(resourceID, uniqueCallerName string)
- func (u Usages) SetReleased(resourceID, uniqueCallerName string, releasedTime time.Time)
- func (u Usages) WaitIfNeeded(resourceID, uniqueCallerName string)
Constants ¶
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
const AcquireRetryLogThreshold = 500 * time.Millisecond
AcquireRetryLogThreshold is the period of time after which an acquire retry will be logged
const MinAllowedPurgerPeriod = time.Second
const UnlockRetryLogThreshold = 100 * time.Millisecond
UnlockRetryLogThreshold is the period of time after which an unlock retry will be logged
Variables ¶
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'
var ErrMongoDbClosing = errors.New("mongo db is being closed")
ErrMongoDbClosing is an error returned because MongoDB is being closed
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'
var GenerateTimeID = func() int { return time.Now().Nanosecond() }
GenerateTimeID returns the current timestamp in nanoseconds
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
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) GetResourceName ¶ added in v1.8.0
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 ¶
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
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
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
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
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
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
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