mysql

package
v0.7.0-rc2 Latest Latest
Warning

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

Go to latest
Published: Jan 13, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package mysql implements a distributed locking mechanism using MySQL/MariaDB advisory locks. It uses the GET_LOCK and RELEASE_LOCK functions to manage exclusive locks.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoDatabase is returned when the database querier is not provided.
	ErrNoDatabase = errors.New("database querier is required")

	// ErrCircuitBreakerOpen is returned when the circuit breaker is open.
	ErrCircuitBreakerOpen = errors.New("circuit breaker open")

	// ErrLockContention is returned when the lock cannot be acquired due to contention.
	ErrLockContention = errors.New("lock contention")
)

Functions

func NewRWLocker

func NewRWLocker(
	ctx context.Context,
	querier database.Querier,
	cfg Config,
	retryCfg lock.RetryConfig,
	allowDegradedMode bool,
) (lock.RWLocker, error)

NewRWLocker creates a new MySQL/MariaDB advisory lock-based RWLocker.

Types

type Config

type Config struct {
	// KeyPrefix is the prefix for all lock keys.
	// If empty, defaults to "ncps:lock:".
	KeyPrefix string

	// CircuitBreakerThreshold is the number of failures before the circuit breaker opens.
	// If zero, defaults to 5.
	CircuitBreakerThreshold int

	// CircuitBreakerResetTimeout is the duration before the circuit breaker tries to close again.
	// If zero, defaults to 30 seconds.
	CircuitBreakerResetTimeout time.Duration
}

Config holds configuration for the MySQL locker.

type Locker

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

Locker implements lock.Locker using MySQL/MariaDB GET_LOCK function. It manages a dedicated connection for each active lock to ensure the lock is held for the duration of the connection.

func NewLocker

func NewLocker(
	ctx context.Context,
	querier database.Querier,
	cfg Config,
	retryCfg lock.RetryConfig,
	allowDegradedMode bool,
) (*Locker, error)

NewLocker creates a new MySQL/MariaDB advisory lock-based locker.

func (*Locker) Lock

func (l *Locker) Lock(ctx context.Context, key string, ttl time.Duration) error

Lock acquires an exclusive lock with retry and exponential backoff. NOTE: MySQL advisory locks are connection-bound and do not support a TTL. The lock is held until Unlock() is called or the underlying database connection is closed (e.g., on application exit). The `ttl` parameter is ignored.

func (*Locker) TryLock

func (l *Locker) TryLock(ctx context.Context, key string, ttl time.Duration) (bool, error)

TryLock attempts to acquire an exclusive lock without retries. It returns true if the lock was acquired, false if it was already held.

func (*Locker) Unlock

func (l *Locker) Unlock(ctx context.Context, key string) error

Unlock releases an exclusive lock by calling RELEASE_LOCK on the dedicated connection. The connection is closed after the lock is released.

type RWLocker

type RWLocker struct {
	*Locker
}

RWLocker implements lock.RWLocker using MySQL/MariaDB GET_LOCK function. Note: MySQL's GET_LOCK is exclusive ONLY. There is no shared lock equivalent. Therefore, RLock behaves exactly like Lock, and RUnlock behaves like Unlock. This matches the behavior of exclusive locking but satisfies the interface. If your application requires high read concurrency that can be shared, consider using Redis or PostgreSQL backends instead.

func (*RWLocker) RLock

func (l *RWLocker) RLock(ctx context.Context, key string, ttl time.Duration) error

RLock acquires a read lock. For MySQL GET_LOCK, this is actually an EXCLUSIVE lock.

func (*RWLocker) RUnlock

func (l *RWLocker) RUnlock(ctx context.Context, key string) error

RUnlock releases a read lock.

Jump to

Keyboard shortcuts

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