lockmanager

package
v0.19.0 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2025 License: MIT Imports: 3 Imported by: 0

README

Contributions Welcome Release

Lock Manager Package

The Lock Manager package provides a unified and extensible distributed locking interface for Go applications. It offers a consistent way to implement distributed locks across different services, making it easy to coordinate access to shared resources in distributed systems.

Features

  • Unified Interface: Consistent API for different lock implementations
  • Redis Implementation: Built-in support for Redis-based distributed locks
    • Customizable Lock Options: Configure lock behavior with options like TTL and retry parameters
    • Context Support: All operations respect context cancellation and deadlines
  • LocalLock Implementation: Simple in-memory lock for local use cases
    • Custom Token Generation: Optionally provide custom token generation logic
    • Auto Cleanup: Locks are automatically cleaned up when ttl expires

Installation

  • LocalLock
    go get github.com/kittipat1413/go-common/framework/lockmanager/locallock
    
  • Redsync
    go get github.com/kittipat1413/go-common/framework/lockmanager/redsync
    

Documentation

Go Reference

For detailed API documentation, examples, and usage patterns, visit the Go Package Documentation.

Usage

Locking Interface The core of the package is the LockManager interface:

type LockManager interface {
	// Acquire attempts to acquire a lock with given key and TTL.
	// Optionally accepts a token; otherwise, one is auto-generated.
	Acquire(ctx context.Context, key string, ttl time.Duration, token ...string) (string, error)

	// Release attempts to release a lock with the given key and token.
	Release(ctx context.Context, key string, token string) error
}
🚀 Getting Started with Redis

Create Redis LockManager

import (
	"github.com/redis/go-redis/v9"
	redsyncLocker "github.com/kittipat1413/go-common/framework/lockmanager/redsync"
)

func main() {
	// Setup Redis client
	client := redis.NewClient(&redis.Options{
		Addr: "localhost:6379",
	})

	// Initialize LockManager
	manager := redsyncLocker.NewRedsyncLockManager(client)
}

🔐 Acquire Lock

ctx := context.Background()
token, err := lockManager.Acquire(ctx, "email-job-lock", 5*time.Second)
if err != nil {
	if errors.Is(err, locker.ErrLockAlreadyTaken) {
		// Handle lock contention
	}
	log.Fatalf("failed to acquire lock: %v", err)
}

🔓 Release Lock

err = lockManager.Release(ctx, "email-job-lock", token)
if err != nil {
	if errors.Is(err, locker.ErrUnlockNotPermitted) {
		// You don't own this lock
	}
	log.Fatalf("failed to release lock: %v", err)
}

⚙️ Advanced Configuration

manager := redsyncLocker.NewRedsyncLockManager(
		client,
		redsyncLocker.WithTokenGenerator(func(key string) string {
			return "lock-token-for:" + key
		}),
		redsyncLocker.WithRedsyncOptions(
			redsync.WithTries(5),                        // Retry up to 5 times
			redsync.WithRetryDelay(50*time.Millisecond), // Wait 50ms between retries
		),
	)

Example

You can find a complete working example in the repository under framework/lockmanager/example.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrLockAlreadyTaken indicates that the lock is already held by another process.
	ErrLockAlreadyTaken = errors.New("lock already taken")
	// ErrUnlockNotPermitted indicates that the unlock operation is not permitted, likely due to a token mismatch.
	ErrUnlockNotPermitted = errors.New("unlock not permitted")
)

Functions

This section is empty.

Types

type LockManager

type LockManager interface {
	// Acquire attempts to acquire a lock for the given key with the specified TTL.
	//
	// If a token is provided, it will be used for the lock identity. If no token is provided,
	// a new unique token will be generated and returned.
	//
	// Returns ErrLockAlreadyTaken if the lock is currently held by another process.
	Acquire(ctx context.Context, key string, ttl time.Duration, token ...string) (string, error)

	// Release attempts to release the lock identified by key and token.
	//
	// Returns ErrUnlockNotPermitted if the token does not match the currently held lock.
	Release(ctx context.Context, key string, token string) error
}

Directories

Path Synopsis
example
locallock command
redsync command
Package locker_mocks is a generated GoMock package.
Package locker_mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

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