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  }