pglock

package module
v1.8.2 Latest Latest
Warning

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

Go to latest
Published: Jan 3, 2022 License: Apache-2.0 Imports: 11 Imported by: 0

README

PostgreSQL Lock Client for Go

Forked from https://github.com/cirello-io/pglock. Vetted by @porowns on January 3rd, 2022 as non-malicious, if we pull any updates we need to check again because this requires access to a database.

Documentation

Index

Constants

View Source
const DefaultHeartbeatFrequency = 5 * time.Second

DefaultHeartbeatFrequency is the recommended frequency that client should refresh the lock so to avoid other clients from stealing it. Use WithHeartbeatFrequency to modify this value.

View Source
const DefaultLeaseDuration = 20 * time.Second

DefaultLeaseDuration is the recommended period of time that a lock can be considered valid before being stolen by another client. Use WithLeaseDuration to modify this value.

View Source
const DefaultTableName = "locks"

DefaultTableName defines the table which the client is going to use to store the content and the metadata of the locks. Use WithCustomTable to modify this value.

Variables

View Source
var (
	ErrDurationTooSmall = errors.New("Heartbeat period must be no more than half the length of the Lease Duration, " +
		"or locks might expire due to the heartbeat thread taking too long to update them (recommendation is to make it much greater, for example " +
		"4+ times greater)")
)

Validation errors

View Source
var ErrLockAlreadyReleased = errors.New("lock is already released")

ErrLockAlreadyReleased indicates that a release call cannot be fulfilled because the client does not hold the lock

View Source
var ErrLockNotFound = &NotExistError{errors.New("lock not found")}

ErrLockNotFound is returned for get calls on missing lock entries.

View Source
var ErrNotAcquired = errors.New("cannot acquire lock")

ErrNotAcquired indicates the given lock is already enforce to some other client.

View Source
var ErrNotPostgreSQLDriver = errors.New("this is not a PostgreSQL connection")

ErrNotPostgreSQLDriver is returned when an invalid database connection is passed to this locker client.

Functions

This section is empty.

Types

type Client

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

Client is the PostgreSQL's backed distributed lock. Make sure it is always configured to talk to leaders and not followers in the case of replicated setups.

func New

func New(db *sql.DB, opts ...ClientOption) (_ *Client, err error)

New returns a locker client from the given database connection. This function validates that *sql.DB holds a ratified postgreSQL driver (lib/pq).

func UnsafeNew

func UnsafeNew(db *sql.DB, opts ...ClientOption) (_ *Client, err error)

UnsafeNew returns a locker client from the given database connection. This function does not check if *sql.DB holds a ratified postgreSQL driver.

func (*Client) Acquire

func (c *Client) Acquire(name string, opts ...LockOption) (*Lock, error)

Acquire attempts to grab the lock with the given key name and wait until it succeeds.

func (*Client) AcquireContext

func (c *Client) AcquireContext(ctx context.Context, name string, opts ...LockOption) (*Lock, error)

AcquireContext attempts to grab the lock with the given key name, wait until it succeeds or the context is done. It returns ErrNotAcquired if the context is canceled before the lock is acquired.

func (*Client) CreateTable

func (c *Client) CreateTable() error

CreateTable prepares a PostgreSQL table with the right DDL for it to be used by this lock client. If the table already exists, it will return an error.

func (*Client) Do

func (c *Client) Do(ctx context.Context, name string, f func(context.Context, *Lock) error, opts ...LockOption) error

Do executes f while holding the lock for the named lock. When the lock loss is detected in the heartbeat, it is going to cancel the context passed on to f. If it ends normally (err == nil), it releases the lock.

func (*Client) Get

func (c *Client) Get(name string) (*Lock, error)

Get returns the lock object from the given name in the table without holding it first.

func (*Client) GetContext

func (c *Client) GetContext(ctx context.Context, name string) (*Lock, error)

GetContext returns the lock object from the given name in the table without holding it first.

func (*Client) GetData

func (c *Client) GetData(name string) ([]byte, error)

GetData returns the data field from the given lock in the table without holding the lock first.

func (*Client) GetDataContext

func (c *Client) GetDataContext(ctx context.Context, name string) ([]byte, error)

GetDataContext returns the data field from the given lock in the table without holding the lock first.

func (*Client) Release

func (c *Client) Release(l *Lock) error

Release will update the mutex entry to be able to be taken by other clients.

func (*Client) ReleaseContext

func (c *Client) ReleaseContext(ctx context.Context, l *Lock) error

ReleaseContext will update the mutex entry to be able to be taken by other clients.

func (*Client) SendHeartbeat

func (c *Client) SendHeartbeat(ctx context.Context, l *Lock) error

SendHeartbeat refreshes the mutex entry so to avoid other clients from grabbing it.

type ClientOption

type ClientOption func(*Client)

ClientOption reconfigures the lock client

func WithCustomTable

func WithCustomTable(tableName string) ClientOption

WithCustomTable reconfigures the lock client to use an alternate lock table name.

func WithHeartbeatFrequency

func WithHeartbeatFrequency(d time.Duration) ClientOption

WithHeartbeatFrequency defines the frequency of the heartbeats. Heartbeats should have no more than half of the duration of the lease.

func WithLeaseDuration

func WithLeaseDuration(d time.Duration) ClientOption

WithLeaseDuration defines how long should the lease be held.

func WithLogger

func WithLogger(l Logger) ClientOption

WithLogger injects a logger into the client, so its internals can be recorded.

func WithOwner

func WithOwner(owner string) ClientOption

WithOwner reconfigures the lock client to use a custom owner name.

type FailedPreconditionError

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

FailedPreconditionError is an error wrapper that gives the FailedPrecondition kind to an error.

func (*FailedPreconditionError) Error

func (err *FailedPreconditionError) Error() string

func (*FailedPreconditionError) Unwrap

func (err *FailedPreconditionError) Unwrap() error

Unwrap returns the next error in the error chain.

type Lock

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

Lock is the mutex entry in the database.

func (*Lock) Close

func (l *Lock) Close() error

Close releases the lock.

func (*Lock) Data

func (l *Lock) Data() []byte

Data returns the content of the lock, if any is available.

func (*Lock) IsReleased

func (l *Lock) IsReleased() bool

IsReleased indicates whether the lock is either released or lost after heartbeat.

func (*Lock) Owner

func (l *Lock) Owner() string

Owner returns who currently owns the lock.

func (*Lock) RecordVersionNumber

func (l *Lock) RecordVersionNumber() int64

RecordVersionNumber is the expectation that this lock entry has about its consistency in the database. If the RecordVersionNumber from the database mismatches the one in the lock, it means that some clock drift has taken place and this lock is no longer valid.

type LockOption

type LockOption func(*Lock)

LockOption reconfigures how the lock behaves on acquire and release.

func FailIfLocked

func FailIfLocked() LockOption

FailIfLocked will not retry to acquire the lock, instead returning.

func KeepOnRelease

func KeepOnRelease() LockOption

KeepOnRelease preserves the lock entry when Close() is called on the lock.

func ReplaceData

func ReplaceData() LockOption

ReplaceData will force the new content to be stored in the lock entry.

func WithCustomHeartbeatContext

func WithCustomHeartbeatContext(ctx context.Context) LockOption

WithCustomHeartbeatContext will override the context used for the heartbeats. It means the cancelation now is responsibility of the caller of the lock.

func WithData

func WithData(data []byte) LockOption

WithData creates lock with data.

type Logger

type Logger interface {
	Println(v ...interface{})
}

Logger is used for internal inspection of the lock client.

type NotExistError

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

NotExistError is an error wrapper that gives the NotExist kind to an error.

func (*NotExistError) Error

func (err *NotExistError) Error() string

func (*NotExistError) Unwrap

func (err *NotExistError) Unwrap() error

Unwrap returns the next error in the error chain.

type OtherError

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

OtherError is an error wrapper that gives the Other kind to an error.

func (*OtherError) Error

func (err *OtherError) Error() string

func (*OtherError) Unwrap

func (err *OtherError) Unwrap() error

Unwrap returns the next error in the error chain.

type UnavailableError

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

UnavailableError is an error wrapper that gives the Unavailable kind to an error.

func (*UnavailableError) Error

func (err *UnavailableError) Error() string

func (*UnavailableError) Unwrap

func (err *UnavailableError) Unwrap() error

Unwrap returns the next error in the error chain.

Jump to

Keyboard shortcuts

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