github.com/zoomfoo/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/nomad/state/notify.go (about) 1 package state 2 3 import ( 4 "sync" 5 ) 6 7 // NotifyGroup is used to allow a simple notification mechanism. 8 // Channels can be marked as waiting, and when notify is invoked, 9 // all the waiting channels get a message and are cleared from the 10 // notify list. 11 type NotifyGroup struct { 12 l sync.Mutex 13 notify map[chan struct{}]struct{} 14 } 15 16 // Notify will do a non-blocking send to all waiting channels, and 17 // clear the notify list 18 func (n *NotifyGroup) Notify() { 19 n.l.Lock() 20 defer n.l.Unlock() 21 for ch := range n.notify { 22 select { 23 case ch <- struct{}{}: 24 default: 25 } 26 } 27 n.notify = nil 28 } 29 30 // Wait adds a channel to the notify group 31 func (n *NotifyGroup) Wait(ch chan struct{}) { 32 n.l.Lock() 33 defer n.l.Unlock() 34 if n.notify == nil { 35 n.notify = make(map[chan struct{}]struct{}) 36 } 37 n.notify[ch] = struct{}{} 38 } 39 40 // Clear removes a channel from the notify group 41 func (n *NotifyGroup) Clear(ch chan struct{}) { 42 n.l.Lock() 43 defer n.l.Unlock() 44 if n.notify == nil { 45 return 46 } 47 delete(n.notify, ch) 48 } 49 50 // WaitCh allocates a channel that is subscribed to notifications 51 func (n *NotifyGroup) WaitCh() chan struct{} { 52 ch := make(chan struct{}, 1) 53 n.Wait(ch) 54 return ch 55 } 56 57 // Empty checks if there are no channels to notify 58 func (n *NotifyGroup) Empty() bool { 59 n.l.Lock() 60 defer n.l.Unlock() 61 return len(n.notify) == 0 62 }