github.com/qxnw/lib4go@v0.0.0-20180426074627-c80c7e84b925/event/delay.go (about)

     1  package event
     2  
     3  import "time"
     4  import "fmt"
     5  
     6  //DelayCallback 延迟回调,多次触发任务时延迟到一定时间后执行,且只执行一次
     7  type DelayCallback struct {
     8  	msg        chan []interface{}
     9  	delayTime  time.Duration
    10  	firstDelay time.Duration
    11  	tkt        *time.Ticker
    12  	callback   func(...interface{})
    13  }
    14  
    15  //NewDelayCallback 创建延迟回调对象
    16  func NewDelayCallback(delayTime time.Duration, firstDelay time.Duration, callback func(...interface{})) (*DelayCallback, error) {
    17  	if callback == nil {
    18  		return nil, fmt.Errorf("回调函数不能为nil")
    19  	}
    20  
    21  	tc := &DelayCallback{delayTime: delayTime, callback: callback, firstDelay: firstDelay}
    22  	tc.msg = make(chan []interface{}, 1)
    23  	go tc.call()
    24  	return tc, nil
    25  }
    26  
    27  //Push 添加触发事件
    28  func (t *DelayCallback) Push(p ...interface{}) {
    29  	select {
    30  	case t.msg <- p:
    31  	default:
    32  	}
    33  }
    34  
    35  //call 回调执行
    36  func (t *DelayCallback) call() {
    37  	time.Sleep(t.firstDelay)
    38  	select {
    39  	case v := <-t.msg:
    40  		// t.callback(v...)
    41  		/*change by champly 2016年12月08日15:36:05*/
    42  		if t.callback != nil {
    43  			t.callback(v...)
    44  		}
    45  		/*end*/
    46  	}
    47  	t.tkt = time.NewTicker(t.delayTime)
    48  START:
    49  	for {
    50  		select {
    51  		case _, ok := <-t.tkt.C:
    52  			{
    53  				if !ok {
    54  					break START
    55  				}
    56  				select {
    57  				case v, ok := <-t.msg:
    58  					if !ok {
    59  						break START
    60  					}
    61  					// t.callback(v...)
    62  					/*change by champly 2016年12月08日15:36:05*/
    63  					if t.callback != nil {
    64  						t.callback(v...)
    65  					}
    66  					/*end*/
    67  				default:
    68  				}
    69  			}
    70  		}
    71  	}
    72  }
    73  
    74  //Close 关闭回调对象
    75  func (t *DelayCallback) Close() {
    76  	if t.tkt != nil {
    77  		t.tkt.Stop()
    78  	}
    79  	close(t.msg)
    80  	/*add by champly 2016年12月08日15:36:23*/
    81  	// 直接关闭报错
    82  	t.callback = nil
    83  	/*end*/
    84  }