func (b *Broadcaster) run() {
	for {
		select {
		case block := <-b.events:
			for _, sink := range b.sinks {
				if err := sink.Write(block...); err != nil {
					logrus.Errorf("broadcaster: error writing events to %v, these events will be lost: %v", sink, err)
				}
			}
		case closing := <-b.closed:
			for _, sink := range b.sinks {
				if err := sink.Close(); err != nil {
					logrus.Errorf("broadcaster: error closing sink %v: %v", sink, err)
				}
			}
			closing <- struct{}{}
			logrus.Debugf("broadcaster: closed")
			return
		}
	}
}
run is the main broadcast loop, started when the broadcaster is created.
Under normal conditions, it waits for events on the event channel. After
Close is called, this goroutine will exit.
package notifications
import (
	"container/list"
	"fmt"
	"sync"
	"time"
	"github.com/Sirupsen/logrus"
)
type Broadcaster struct {
	sinks  []Sink
	events chan []Event
	closed chan chan struct{}
}
func NewBroadcaster(sinks ...Sink) *Broadcaster {
	b := Broadcaster{
		sinks:  sinks,
		events: make(chan []Event),
		closed: make(chan chan struct{}),
	}
	go b.run()
	return &b
}
func (b *Broadcaster) Write(events ...Event) error {
	select {
	case b.events <- events:
	case <-b.closed:
		return ErrSinkClosed
	}
	return nil
}
func (b *Broadcaster) Close() error {
	logrus.Infof("broadcaster: closing")
	select {
	case <-b.closed:
		return fmt.Errorf("broadcaster: already closed")
	default:
		closed := make(chan struct{})
		b.closed <- closed
		close(b.closed)
		<-closed
		return nil
	}
}