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 }