github.com/djenriquez/nomad-1@v0.8.1/client/structs/funcs.go (about)

     1  package structs
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/hashicorp/nomad/nomad/structs"
     7  )
     8  
     9  // AllocBroadcaster implements an allocation broadcast channel.
    10  // The zero value is a usable unbuffered channel.
    11  type AllocBroadcaster struct {
    12  	m         sync.Mutex
    13  	listeners map[int]chan<- *structs.Allocation // lazy init
    14  	nextId    int
    15  	capacity  int
    16  	closed    bool
    17  }
    18  
    19  // NewAllocBroadcaster returns a new AllocBroadcaster with the given capacity (0 means unbuffered).
    20  func NewAllocBroadcaster(n int) *AllocBroadcaster {
    21  	return &AllocBroadcaster{capacity: n}
    22  }
    23  
    24  // AllocListener implements a listening endpoint for an allocation broadcast channel.
    25  type AllocListener struct {
    26  	// Ch receives the broadcast messages.
    27  	Ch <-chan *structs.Allocation
    28  	b  *AllocBroadcaster
    29  	id int
    30  }
    31  
    32  // Send broadcasts a message to the channel. Send returns whether the message
    33  // was sent to all channels.
    34  func (b *AllocBroadcaster) Send(v *structs.Allocation) bool {
    35  	b.m.Lock()
    36  	defer b.m.Unlock()
    37  	if b.closed {
    38  		return false
    39  	}
    40  	sent := true
    41  	for _, l := range b.listeners {
    42  		select {
    43  		case l <- v:
    44  		default:
    45  			sent = false
    46  		}
    47  	}
    48  
    49  	return sent
    50  }
    51  
    52  // Close closes the channel, disabling the sending of further messages.
    53  func (b *AllocBroadcaster) Close() {
    54  	b.m.Lock()
    55  	defer b.m.Unlock()
    56  	if b.closed {
    57  		return
    58  	}
    59  
    60  	b.closed = true
    61  	for _, l := range b.listeners {
    62  		close(l)
    63  	}
    64  }
    65  
    66  // Listen returns a Listener for the broadcast channel.
    67  func (b *AllocBroadcaster) Listen() *AllocListener {
    68  	b.m.Lock()
    69  	defer b.m.Unlock()
    70  	if b.listeners == nil {
    71  		b.listeners = make(map[int]chan<- *structs.Allocation)
    72  	}
    73  	for b.listeners[b.nextId] != nil {
    74  		b.nextId++
    75  	}
    76  	ch := make(chan *structs.Allocation, b.capacity)
    77  	if b.closed {
    78  		close(ch)
    79  	}
    80  	b.listeners[b.nextId] = ch
    81  	return &AllocListener{ch, b, b.nextId}
    82  }
    83  
    84  // Close closes the Listener, disabling the receival of further messages.
    85  func (l *AllocListener) Close() {
    86  	l.b.m.Lock()
    87  	defer l.b.m.Unlock()
    88  	delete(l.b.listeners, l.id)
    89  }