| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- package trylock
- import (
- "context"
- "sync"
- "time"
- "github.com/labring/aiproxy/core/common"
- log "github.com/sirupsen/logrus"
- )
- var memRecord = sync.Map{}
- func init() {
- go cleanMemLock()
- }
- func cleanMemLock() {
- ticker := time.NewTicker(30 * time.Second)
- defer ticker.Stop()
- for now := range ticker.C {
- memRecord.Range(func(key, value any) bool {
- exp, ok := value.(time.Time)
- if !ok || now.After(exp) {
- memRecord.CompareAndDelete(key, value)
- }
- return true
- })
- }
- }
- func MemLock(key string, expiration time.Duration) bool {
- now := time.Now()
- newExpiration := now.Add(expiration)
- for {
- actual, loaded := memRecord.LoadOrStore(key, newExpiration)
- if !loaded {
- return true
- }
- oldExpiration, ok := actual.(time.Time)
- if !ok {
- memRecord.CompareAndDelete(key, actual)
- continue
- }
- if now.After(oldExpiration) {
- if memRecord.CompareAndSwap(key, actual, newExpiration) {
- return true
- }
- continue
- }
- return false
- }
- }
- func Lock(key string, expiration time.Duration) bool {
- if !common.RedisEnabled {
- return MemLock(key, expiration)
- }
- ctx, cancel := context.WithTimeout(context.Background(), time.Second)
- defer cancel()
- result, err := common.RDB.SetNX(ctx, key, true, expiration).Result()
- if err != nil {
- if MemLock("lockerror", time.Second*3) {
- log.Errorf("try notify error: %v", err)
- }
- return MemLock(key, expiration)
- }
- return result
- }
|