Documentation
¶
Index ¶
- Variables
- type Client
- func (c *Client) Lock(ctx context.Context, key string, expiration time.Duration, retry RetryStrategy, ...) (*Lock, error)
- func (c *Client) SingleflightLock(ctx context.Context, key string, expiration time.Duration, retry RetryStrategy, ...) (*Lock, error)
- func (c *Client) TryLock(ctx context.Context, key string, expiration time.Duration) (*Lock, error)
- type FixIntervalRetry
- type Lock
- type RetryStrategy
Examples ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ( ErrFailedToPreemptLock = errors.New("rlock: 抢锁失败") // ErrLockNotHold 一般是出现在你预期你本来持有锁,结果却没有持有锁的地方 // 比如说当你尝试释放锁的时候,可能得到这个错误 // 这一般意味着有人绕开了 rlock 的控制,直接操作了 Redis ErrLockNotHold = errors.New("rlock: 未持有锁") )
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func (*Client) Lock ¶
func (c *Client) Lock(ctx context.Context, key string, expiration time.Duration, retry RetryStrategy, timeout time.Duration) (*Lock, error)
Lock 是尽可能重试减少加锁失败的可能 Lock 会在超时或者锁正被人持有的时候进行重试 最后返回的 error 使用 errors.Is 判断,可能是: - context.DeadlineExceeded: Lock 整体调用超时 - ErrFailedToPreemptLock: 超过重试次数,但是整个重试过程都没有出现错误 - DeadlineExceeded 和 ErrFailedToPreemptLock: 超过重试次数,但是最后一次重试超时了 在使用的过程中,应该注意: - 如果 errors.Is(err, context.DeadlineExceeded) 那么最终有没有加锁成功,谁也不知道 - 如果 errors.Is(err, ErrFailedToPreemptLock) 说明肯定没成功,而且超过了重试次数 - 否则,和 Redis 通信出了问题
func (*Client) SingleflightLock ¶
type FixIntervalRetry ¶
type Lock ¶
type Lock struct {
// contains filtered or unexported fields
}
func (*Lock) AutoRefresh ¶
AutoRefresh 自动续约简单实现,可控性差 如果需要万无一失使用这个分布式锁,那么必须手动调用Refresh 可查看Refresh的example,自己手动处理各种error通信及业务中断
Example ¶
var l *Lock
go func() {
// 如果返回error,需要中断业务或只打印错误日志,根据用户业务决定
l.AutoRefresh(time.Second*10, time.Second)
}()
func (*Lock) Refresh ¶
Refresh 手动续约
Example ¶
var lock *Lock
end := make(chan struct{}, 1)
go func() {
ticker := time.NewTicker(time.Second * 30)
for {
select {
case <-ticker.C:
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
err := lock.Refresh(ctx)
cancel()
// 错误处理
if errors.Is(err, context.DeadlineExceeded) {
// 超时,应该立刻重试
// 超时之下可能续约成功了,也可能没成功
}
if err != nil {
// 其它错误,要考虑这个错误能不能继续处理
// 如果不能处理,怎么通知后续业务中断?
}
case <-end:
// 你的业务退出了
}
}
}()
// 后面是你的业务
fmt.Println("Finish")
// 你的业务完成了
end <- struct{}{}
Output: Finish
type RetryStrategy ¶
Click to show internal directories.
Click to hide internal directories.