gitee.com/quant1x/gox@v1.7.6/cron/scheduler.go (about)

     1  package cron
     2  
     3  import (
     4  	"sync"
     5  	"sync/atomic"
     6  	"time"
     7  )
     8  
     9  const (
    10  	crontabInterval  = 10
    11  	crontabSnapshot  = "0/1 * * * * ?"
    12  	sleepMillisecond = 1
    13  )
    14  
    15  type Scheduler struct {
    16  	crontabInterval float64 // 单位是秒
    17  	crontabSequence int64
    18  	m               sync.Mutex
    19  	cron            *Cron
    20  	service         func()
    21  }
    22  
    23  // NewScheduler 创建一个业务定时器
    24  func NewScheduler(interval int, service func()) *Scheduler {
    25  	crontab := Scheduler{
    26  		crontabInterval: float64(interval),
    27  		crontabSequence: 0,
    28  		service:         service,
    29  	}
    30  	crontab.cron = New(WithSeconds())
    31  	return &crontab
    32  }
    33  
    34  func (this *Scheduler) Run() error {
    35  	_, err := this.cron.AddFunc(crontabSnapshot, func() {
    36  		for atomic.LoadInt64(&this.crontabSequence) != 0 {
    37  			return
    38  		}
    39  		this.m.Lock()
    40  		defer this.m.Unlock()
    41  		if this.crontabSequence != 0 {
    42  			return
    43  		}
    44  		atomic.StoreInt64(&this.crontabSequence, 1)
    45  		now := time.Now()
    46  		// 执行业务
    47  		this.service()
    48  		atomic.StoreInt64(&this.crontabSequence, 0)
    49  		diffDuration := float64(sleepMillisecond) / 1000.00
    50  		for {
    51  			elapsedTime := time.Since(now).Seconds()
    52  			if elapsedTime+diffDuration < this.crontabInterval {
    53  				sleepStart := time.Now()
    54  				time.Sleep(time.Millisecond * sleepMillisecond)
    55  				diffDuration = float64(time.Since(sleepStart).Milliseconds()) / 1000
    56  			} else {
    57  				break
    58  			}
    59  		}
    60  	})
    61  	if err != nil {
    62  		return err
    63  	}
    64  	this.cron.Start()
    65  	return nil
    66  }