dlock

package
v1.12.3 Latest Latest
Warning

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

Go to latest
Published: Jan 20, 2025 License: MIT Imports: 8 Imported by: 0

README

dlock

dlock is a distributed lock library based on redsync and etcd. It provides a simple and easy-to-use API for acquiring and releasing locks.


Example of use

Redis Lock
package main

import (
    "context"
    "fmt"
    "time"
    "github.com/go-dev-frame/sponge/pkg/goredis"
    "github.com/go-dev-frame/sponge/pkg/dlock"
)

func main() {
    redisCli, err := goredis.Init("default:123456@192.168.3.37:6379")  // single redis instance
    // clusterRedisCli, err := goredis.InitCluster(...)                // or init redis cluster
    // redisCli, err := goredis.InitSentinel(...)                      // or init redis sentinel
    if err != nil {
        panic(err)
    }
    defer redisCli.Close()

    locker, err := dlock.NewRedisLock(redisCli, "test_lock")
    if err != nil {
        panic(err)
    }
    ctx, _ := context.WithTimeout(context.Background(), time.Second*10)

    // case 1: try to acquire lock, unblock if failed
    {
        ok, err := locker.TryLock(ctx)
        if err != nil {
            panic(err)
        }
        if !ok {
            fmt.Println("failed to acquire lock")
            return
        }
        defer func() {
            if err := locker.Unlock(ctx); err != nil {
                panic(err)
            }
        }()
        // do something here
    }

    // case 2: lock acquired, block until released, timeout, ctx error
    {
        if err := locker.Lock(ctx); err != nil {
            panic(err)
        }
        defer func() {
            if err := locker.Unlock(ctx); err != nil {
                panic(err)
            }
        }()
        // do something here
    }
}

Etcd Lock
package main

import (
    "context"
    "fmt"
    "time"
    "github.com/go-dev-frame/sponge/pkg/etcdcli"
    "github.com/go-dev-frame/sponge/pkg/dlock"
)

func main() {
    endpoints := []string{"192.168.3.37:2379"}
    cli, err := etcdcli.Init(endpoints,  etcdcli.WithConnectTimeout(time.Second*5))
    if err!= nil {
        panic(err)
    }
    defer cli.Close()

    locker, err := dlock.NewEtcd(cli, "sponge/dlock", 10)
    if err != nil {
        panic(err)
    }
    ctx, _ := context.WithTimeout(context.Background(), time.Second*10)

    // case 1: try to acquire lock, unblock if failed
    {
        ok, err := locker.TryLock(ctx)
        if err != nil {
            panic(err)
        }
        if !ok {
            fmt.Println("failed to acquire lock")
            return
        }
        defer func() {
            if err := locker.Unlock(ctx); err != nil {
                panic(err)
            }
        }()
        // do something here
    }

    // case 2: lock acquired, block until released, timeout, ctx error
    {
        if err := locker.Lock(ctx); err != nil {
            panic(err)
        }
        defer func() {
            if err := locker.Unlock(ctx); err != nil {
                panic(err)
            }
        }()
        // do something here
    }
}

Documentation

Overview

Package dlock provides distributed locking primitives, supports redis and etcd.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type EtcdLock

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

func (*EtcdLock) Close

func (l *EtcdLock) Close() error

Close releases the lock and the etcd session.

func (*EtcdLock) Lock

func (l *EtcdLock) Lock(ctx context.Context) error

Lock blocks until the lock is acquired or the context is canceled.

func (*EtcdLock) TryLock

func (l *EtcdLock) TryLock(ctx context.Context) (bool, error)

TryLock tries to acquire the lock without blocking.

func (*EtcdLock) Unlock

func (l *EtcdLock) Unlock(ctx context.Context) error

Unlock releases the lock.

type Locker

type Locker interface {
	Lock(ctx context.Context) error
	Unlock(ctx context.Context) error
	TryLock(ctx context.Context) (bool, error)
	Close() error
}

Locker is the interface that wraps the basic locking operations.

func NewEtcd

func NewEtcd(client *clientv3.Client, key string, ttl int) (Locker, error)

NewEtcd creates a new etcd locker with the given key and ttl.

func NewRedisClusterLock

func NewRedisClusterLock(clusterClient *redis.ClusterClient, key string, options ...redsync.Option) (Locker, error)

NewRedisClusterLock creates a new RedisClusterLock.

func NewRedisLock

func NewRedisLock(client *redis.Client, key string, options ...redsync.Option) (Locker, error)

NewRedisLock creates a new RedisLock.

type RedisLock

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

RedisLock implements Locker using Redis.

func (*RedisLock) Close

func (l *RedisLock) Close() error

Close no-op for RedisLock.

func (*RedisLock) Lock

func (l *RedisLock) Lock(ctx context.Context) error

Lock blocks until the lock is acquired or the context is canceled.

func (*RedisLock) TryLock

func (l *RedisLock) TryLock(ctx context.Context) (bool, error)

TryLock tries to acquire the lock without blocking.

func (*RedisLock) Unlock

func (l *RedisLock) Unlock(ctx context.Context) error

Unlock releases the lock, if unlocking the key is successful, the key will be automatically deleted

Jump to

Keyboard shortcuts

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