goconsistencehash/local/blocklock.go
2025-05-07 10:34:10 +08:00

65 lines
1001 B
Go

package local
import (
"context"
"errors"
"git.zhangshuocauc.cn/redhat/goconsistencehash/local/os"
"sync"
"time"
)
type BlockLock struct {
mu sync.Mutex
dmu sync.Mutex
token string
calFn context.CancelFunc
}
func (b *BlockLock) Lock(ctx context.Context, expire int) error {
b.mu.Lock()
b.dmu.Lock()
defer b.dmu.Unlock()
token := os.GetCurrentProcessAndGoroutineIDStr()
b.token = token
b.calFn = nil
var sctx context.Context
sctx, b.calFn = context.WithCancel(ctx)
go func() {
select {
case <-sctx.Done():
return
case <-time.After(time.Duration(expire) * time.Second):
_ = b.unLock(token)
}
}()
return nil
}
func (b *BlockLock) unLock(id string) error {
b.dmu.Lock()
defer b.dmu.Unlock()
if b.token != id {
return errors.New("not my lock")
}
if b.calFn != nil {
b.calFn()
}
b.token = ""
b.mu.Unlock()
return nil
}
func (b *BlockLock) UnLock(context.Context) error {
id := os.GetCurrentProcessAndGoroutineIDStr()
return b.unLock(id)
}