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  }