gitee.com/quant1x/gox@v1.21.2/coroutine/rolling_mutex.go (about) 1 package coroutine 2 3 import ( 4 "sync" 5 "sync/atomic" 6 "time" 7 ) 8 9 const ( 10 onceInitTime = "09:00:00" 11 onceDefaultDate = "1970-01-01" 12 ) 13 14 // RollingMutex 按指定rolling策略加锁, 指定周期内只加载一次 15 // 16 // 滑动窗口锁, 窗口期内只初始化一次, 目前只支持1天切换 17 // 18 // Deprecated: 不推荐, 建议使用 RollingOnce 19 type RollingMutex struct { 20 m sync.Mutex 21 date string 22 done uint32 23 } 24 25 // 校对当前日期 26 func (o *RollingMutex) proofreadCurrentDate() (currentDate string) { 27 currentDate = o.date 28 if currentDate < onceDefaultDate { 29 currentDate = onceDefaultDate 30 } 31 now := time.Now() 32 timestamp := now.Format(time.TimeOnly) 33 if timestamp >= onceInitTime { 34 currentDate = now.Format(time.DateOnly) 35 } 36 return currentDate 37 } 38 39 func (o *RollingMutex) Do(f func(), today ...func() (newDate string)) { 40 getToday := o.proofreadCurrentDate 41 if len(today) > 0 { 42 getToday = today[0] 43 } 44 if getToday != nil { 45 currentDate := getToday() 46 if atomic.LoadUint32(&o.done) == 1 && currentDate > o.date { 47 o.doReset(currentDate) 48 } 49 } 50 if atomic.LoadUint32(&o.done) == 0 { 51 o.doSlow(f) 52 } 53 } 54 55 func (o *RollingMutex) doReset(currentDate string) { 56 o.m.Lock() 57 defer o.m.Unlock() 58 if o.done == 1 && currentDate > o.date { 59 atomic.StoreUint32(&o.done, 0) 60 o.date = currentDate 61 } 62 } 63 64 func (o *RollingMutex) doSlow(f func()) { 65 o.m.Lock() 66 defer o.m.Unlock() 67 if o.done == 0 { 68 defer atomic.StoreUint32(&o.done, 1) 69 f() 70 } 71 } 72 73 func (o *RollingMutex) Reset() { 74 atomic.StoreUint32(&o.done, 0) 75 } 76 77 func (o *RollingMutex) Date() string { 78 return o.date 79 }