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

     1  package event
     2  
     3  import "sync"
     4  import "fmt"
     5  
     6  //Once 一次执行锁,相同事件多次完成时只释放一次锁
     7  type Once struct {
     8  	sync    *sync.WaitGroup
     9  	lk      *sync.Mutex
    10  	actions map[string]int
    11  }
    12  
    13  //NewOnce 构建一次执行(防止相同的事件多次进入)锁
    14  func NewOnce(wait int) (sn Once, err error) {
    15  	/*add by champly 2016年12月08日14:17:57*/
    16  	if wait <= 0 {
    17  		err = fmt.Errorf("wait must greater than zero")
    18  		return
    19  	}
    20  	/*end*/
    21  
    22  	sn = Once{}
    23  	sn.lk = &sync.Mutex{}
    24  	sn.sync = &sync.WaitGroup{}
    25  	sn.actions = make(map[string]int)
    26  	sn.sync.Add(wait)
    27  	return
    28  }
    29  
    30  //Wait 等待所有执行完成
    31  func (s Once) Wait() {
    32  	s.sync.Wait()
    33  }
    34  
    35  //WaitAndAdd 等待所有执行完成并添加新的任务
    36  func (s Once) WaitAndAdd(delta int) {
    37  	s.sync.Wait()
    38  	s.sync.Add(delta)
    39  }
    40  
    41  //AddStep 添加执行步骤
    42  func (s Once) AddStep(delta int) {
    43  	s.sync.Add(delta)
    44  }
    45  
    46  //Done 完成任务
    47  func (s Once) Done(action string) {
    48  	s.lk.Lock()
    49  	defer s.lk.Unlock()
    50  	if _, ok := s.actions[action]; !ok {
    51  		s.actions[action] = 1
    52  		s.sync.Done()
    53  	}
    54  }
    55  
    56  //Close 关闭当前锁
    57  func (s Once) Close() {
    58  	for i := range s.actions {
    59  		delete(s.actions, i)
    60  	}
    61  }