client

package module
v0.0.0-...-bf0d46e Latest Latest
Warning

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

Go to latest
Published: Apr 20, 2024 License: GPL-3.0 Imports: 5 Imported by: 3

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrLockNotExists = errors.New("lock not exists")

Functions

This section is empty.

Types

type Lock

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

func (*Lock) Refresh

func (l *Lock) Refresh(ctx context.Context, ttl time.Duration) *LockError

Refresh 使用新的 TTL 刷新延长锁的时间 如果刷新没有成功,有可能返回 ErrNotObtained

func (*Lock) Release

func (l *Lock) Release()

Release 手动释放锁,不要忘记释放锁

func (*Lock) TTL

func (l *Lock) TTL() (time.Duration, error)

TTL 返回剩余的生存时间,如果锁过期,返回 0

type LockError

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

LockError 获取锁返回的错误 Err() 表示获取锁未成功(包括 redis 操作失败、锁被占用的情况下获取不到锁等)

如需要判断锁被占用的情况下,获取不到锁,使用 ErrNotObtained()

if lockErr.ErrNotObtained() {
	锁被占用,获取不到锁
} else if lockErr.Err() != nil {
	redis 操作失败
}

func (*LockError) Err

func (le *LockError) Err() error

Err 返回错误,包括 redis 操作错误 和 未获取到锁错误

func (*LockError) ErrNotObtained

func (le *LockError) ErrNotObtained() bool

ErrNotObtained 是否未成功获取到锁(锁被占用) true: 未获取到锁

func (*LockError) Error

func (le *LockError) Error() string

type Redis

type Redis struct {
	*redis.Client
	// contains filtered or unexported fields
}

func NewRedisClient

func NewRedisClient(opt *redis.Options) (*Redis, error)

func (*Redis) ObtainLockDeadline

func (r *Redis) ObtainLockDeadline(ctx context.Context, key string, ttl, wait, backoff time.Duration) (lock *Lock, cancel func(), lockError *LockError)

ObtainLockDeadline 每 backoff 时间重试一次获取锁,直到 wait 时间,如果还未获取到锁则返回

example: ttl is 1s,Retry every 500ms, for up-to a minute ObtainLockDeadline(context.Background(), "key", time.Second, time.Minute, 500 * time.Millisecond)

Example
lock, cancel, lockErr := redisClient.ObtainLockDeadline(
	context.Background(),
	"redis:key",
	time.Second*5,
	time.Second,
	time.Millisecond*500,
)
if lockErr.ErrNotObtained() {
	// 没有获取到锁
} else if lockErr.Err() != nil {
	// 没有获取到锁,或者 redis 操作错误
	log.Fatal(lockErr.Error())
}

// 取消获取锁
defer cancel()

// 释放锁
lock.Release()
Output:

func (*Redis) ObtainLockOnce

func (r *Redis) ObtainLockOnce(ctx context.Context, key string, ttl time.Duration) (*Lock, *LockError)

ObtainLockOnce 直接获取锁,只获取一次,redis 处理失败或者获取不到锁(锁被占用)直接返回

Example
var err error
redisClient, err = NewRedisClient(&redis2.Options{
	Network:  "tcp",
	Addr:     "127.0.0.1:6379",
	Password: "",
	DB:       0,
})

if err != nil {
	panic(err)
}

lock, lockErr := redisClient.ObtainLockOnce(context.Background(), "redis:key", time.Millisecond*500)
if lockErr.ErrNotObtained() {
	// 没有获取到锁
} else if lockErr.Err() != nil {
	// 没有获取到锁,或者 redis 操作错误
	log.Fatal(lockErr.Error())
}

// 释放锁
lock.Release()

// 返回剩余的生存时间
_, _ = lock.TTL()
Output:

func (*Redis) ObtainLockRetry

func (r *Redis) ObtainLockRetry(ctx context.Context, key string, ttl time.Duration, retryNum int, backoff time.Duration) (*Lock, *LockError)

ObtainLockRetry 每 backoff 时间重试一次获取锁,最多重试 retryNum 次数,如果还未获取到锁则返回

example: Retry every 100ms, for up-to 3x ObtainLockRetry(context.Background(), "key", time.Second, 3, 100 * time.Millisecond)

Example
lock, lockErr := redisClient.ObtainLockRetry(
	context.Background(),
	"redis:key",
	time.Second*10,
	5,
	time.Second,
)
if lockErr.ErrNotObtained() {
	// 没有获取到锁
} else if lockErr.Err() != nil {
	// 没有获取到锁,或者 redis 操作错误
	log.Fatal(lockErr.Error())
}

// 释放锁
lock.Release()
Output:

Jump to

Keyboard shortcuts

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