Documentation ¶
Index ¶
- Constants
- Variables
- type FakeLockProvider
- type FakePreemptableLock
- type LockProvider
- type LockProviderConfig
- type LockProviderKind
- type LockProviderOption
- type NotificationPayload
- type PostgresEnvLock
- type PostgresLock
- type PostgresLockProvider
- type PreemptableLock
- type PreemptiveLocker
- type PreemptiveLockerConfig
- type PreemptiveLockerFactory
- func NewFakePreemptiveLockerFactory(providerOpts []LockProviderOption, lockerOpts ...PreemptiveLockerOption) (PreemptiveLockerFactory, error)
- func NewPostgresPreemptiveLockerFactory(postgresURI, apmServiceName string, providerOpts []LockProviderOption, ...) (PreemptiveLockerFactory, error)
- func NewPreemptiveLockerFactory(provider LockProvider, opts ...PreemptiveLockerOption) (PreemptiveLockerFactory, error)
- type PreemptiveLockerOption
Constants ¶
const ( // UnknownLockProviderKind is the default kind and is unimplmeneted UnknownLockProviderKind = iota // PostgresLockProviderKind represents an implementation of the LockProvider interface that uses Postgres as the underlying store PostgresLockProviderKind // FakeLockProviderKind represents an implementation of the LockProvider interfaces that uses an in-memory store, suitable for tests FakeLockProviderKind )
Variables ¶
var ErrLockPreempted = errors.New("lock was preemptepd while waiting for the lock")
Functions ¶
This section is empty.
Types ¶
type FakeLockProvider ¶ added in v0.8.0
type FakeLockProvider struct {
// contains filtered or unexported fields
}
FakeLockProvider can serve as a lock provider with no external dependencies
func (*FakeLockProvider) New ¶ added in v0.8.0
func (flp *FakeLockProvider) New(ctx context.Context, key int64, event string) (PreemptableLock, error)
type FakePreemptableLock ¶
type FakePreemptableLock struct {
// contains filtered or unexported fields
}
func (*FakePreemptableLock) Lock ¶
func (fpl *FakePreemptableLock) Lock(ctx context.Context) (<-chan NotificationPayload, error)
type LockProvider ¶
type LockProvider interface { New(ctx context.Context, key int64, event string) (PreemptableLock, error) LockKey(ctx context.Context, repo string, pr uint) (int64, error) }
LockProvider describes an object capable of creating distributed locks. You may provide your own int64 key or obtain one for a given Repo/PR.
func NewLockProvider ¶ added in v0.8.0
func NewLockProvider(kind LockProviderKind, options ...LockProviderOption) (LockProvider, error)
NewLockProvider returns an implementation of the LockProvider interface. It accepts an arbitrary number of LockProviderOptions and sets some opinonated default values if the option is not explicitly set.
type LockProviderConfig ¶ added in v0.8.0
type LockProviderConfig struct {
// contains filtered or unexported fields
}
LockProviderConfig sets configuration values that can be shared between LockProvider implementations.
type LockProviderKind ¶ added in v0.8.0
type LockProviderKind int
LockProviderKind enumerates the different LockProvider implementations
type LockProviderOption ¶ added in v0.8.0
type LockProviderOption func(*LockProviderConfig)
LockProviderOptions allows clients to configure different aspects for the LockProvider return from NewLockProvider
func WithLockTimeout ¶ added in v0.8.0
func WithLockTimeout(lockWait time.Duration) LockProviderOption
WithLockTimeout sets the duration for which the lock will block while attempting to lock, before it gives up and returns an error.
func WithMaxLockDuration ¶ added in v0.8.0
func WithMaxLockDuration(duration time.Duration) LockProviderOption
WithMaxLockDuration sets the duration for which the lock will wait before automatically unlocking the lock. This can be used to protect against the holder of the lock getting blocked or not being able to unlock the lock.
func WithPostgresBackend ¶ added in v0.8.0
func WithPostgresBackend(postgresURI string, apmServiceName string) LockProviderOption
WithPostgresBackend allows for a distributed lock provider backed by Postgres. APM traces can also be enabled with the configured service name.
func WithPreemptionTimeout ¶ added in v0.8.0
func WithPreemptionTimeout(duration time.Duration) LockProviderOption
WithPreemptionTimeout sets the duration for which the lock will wait for the holder to respect a notification and release the lock. If a notification is sent to the lock, the lock will be released after this duration no matter what the holder does. This provides a mechanism for releasing the lock quickly in scenarios where the holder of the lock may be blocked indefinitely.
type NotificationPayload ¶ added in v0.8.0
type NotificationPayload struct { // ID is required so that we can ensure the message came from another party. ID uuid.UUID `json:"id"` // Message provides some context as to why the notification was generated. // Useful for logging purposes. Message string `json:"event"` // The key that this Notification Payload pertains to LockKey int64 `json:"lockKey"` }
NotificationPayload represents the content of messages sent to the lock holder.
type PostgresEnvLock ¶ added in v0.8.0
PostgresEnvLock models a distributed lock associated with a unique repo/PR combination
func (PostgresEnvLock) Columns ¶ added in v0.8.0
func (el PostgresEnvLock) Columns() string
func (PostgresEnvLock) ScanValues ¶ added in v0.8.0
func (el PostgresEnvLock) ScanValues() []interface{}
type PostgresLock ¶ added in v0.8.0
type PostgresLock struct {
// contains filtered or unexported fields
}
func NewPostgresLock ¶ added in v0.8.0
func NewPostgresLock(ctx context.Context, db *sqlx.DB, key int64, connInfo, message string, conf LockProviderConfig) (pl *PostgresLock, err error)
func (*PostgresLock) Lock ¶ added in v0.8.0
func (pl *PostgresLock) Lock(ctx context.Context) (<-chan NotificationPayload, error)
func (*PostgresLock) Notify ¶ added in v0.8.0
func (pl *PostgresLock) Notify(ctx context.Context) error
Notify lets other processes know that they should release the lock. In this case, we use the Postgres NOTIFY command to let the other processes know. It is up to the other locks to LISTEN and release the lock accordingly.
type PostgresLockProvider ¶ added in v0.8.0
type PostgresLockProvider struct {
// contains filtered or unexported fields
}
func (*PostgresLockProvider) New ¶ added in v0.8.0
func (plp *PostgresLockProvider) New(ctx context.Context, key int64, event string) (PreemptableLock, error)
type PreemptableLock ¶
type PreemptableLock interface { // Lock locks the preemptable lock. If it fails to lock, or is preempted before locking, it should return an error Lock(ctx context.Context) (<-chan NotificationPayload, error) // Unlock unlocks the preemptable lock. It should clean up any underlying resources Unlock(ctx context.Context) error // Notify informs the current lock holder that they should unlock the lock Notify(ctx context.Context) error }
PreemptableLock describes an object that acts as a Lock that can signal to peers that they should unlock Preemptable locks are single use. Once you unlock the lock, underlying resources will be cleaned up
type PreemptiveLocker ¶
type PreemptiveLocker struct {
// contains filtered or unexported fields
}
PreemptiveLocker represents a distributed lock where callers can be preempted while waiting for the lock to be released or while holding the lock. High level, the algorithm is as follows: - Client A calls Lock() which returns immediately, Client A now has the lock. Client A periodically ensures the session is still alive. If Client A dies, the session expires and the lock is automatically released. - Client B calls Lock() which blocks since the lock is held by Client A. - Client A receives a value on the channel returned from the Lock() call indicating Client A should release the lock ASAP - Client C calls Lock() which blocks - Client B's invocation of Lock() returns with an error indicating it was preempted while waiting for the lock to release - Client A calls Unlock() - Client C's invocation of Lock() returns successfully
func (*PreemptiveLocker) Lock ¶
func (p *PreemptiveLocker) Lock(ctx context.Context) (ch <-chan NotificationPayload, err error)
Lock locks the lock and returns a channel used to signal if the lock should be released ASAP. If the lock is currently in use, this method will block until the lock is released. If the caller is preempted while waiting for the lock to be released, an error is returned.
type PreemptiveLockerConfig ¶ added in v0.8.0
type PreemptiveLockerConfig struct {
// contains filtered or unexported fields
}
PreemptiveLockerConfig contains values for adjusting how the PreemptiveLocker behaves
type PreemptiveLockerFactory ¶ added in v0.8.0
type PreemptiveLockerFactory func(repo string, pr uint, event string) *PreemptiveLocker
func NewFakePreemptiveLockerFactory ¶ added in v0.8.0
func NewFakePreemptiveLockerFactory(providerOpts []LockProviderOption, lockerOpts ...PreemptiveLockerOption) (PreemptiveLockerFactory, error)
NewFakePreemptiveLockerFactory will create a PreemptiveLockerFactory that makes use of a FakeLockProvider. This is suitable for tests, where postgres might not be available or wanted.
func NewPostgresPreemptiveLockerFactory ¶ added in v0.8.0
func NewPostgresPreemptiveLockerFactory(postgresURI, apmServiceName string, providerOpts []LockProviderOption, lockerOpts ...PreemptiveLockerOption) (PreemptiveLockerFactory, error)
NewPostgresPreemptiveLockerFactory will create a PreemptiveLockerFactory that makes use of a PostgresLockProvider.
func NewPreemptiveLockerFactory ¶ added in v0.8.0
func NewPreemptiveLockerFactory(provider LockProvider, opts ...PreemptiveLockerOption) (PreemptiveLockerFactory, error)
NewPreemptiveLockerFactory
type PreemptiveLockerOption ¶ added in v0.8.0
type PreemptiveLockerOption func(*PreemptiveLockerConfig)
func WithAPMServiceName ¶ added in v0.8.0
func WithAPMServiceName(name string) PreemptiveLockerOption
func WithLockDelay ¶ added in v0.8.0
func WithLockDelay(lockDelay time.Duration) PreemptiveLockerOption