func NewNotifyDispatcher(l Listener) *NotifyDispatcher {
	d := &NotifyDispatcher{
		listener: l,
		slowReaderEliminationStrategy: CloseSlowReaders,
		broadcastOnConnectionLoss: true,
		broadcastChannels: list.New(),
		listenRequestch: make(chan listenRequest, 64),
		channels: make(map[string] *listenSet),
		closeChannel: make(chan bool),
	}
	go d.dispatcherLoop()
	go d.listenRequestHandlerLoop()
	return d
}
NewNotifyDispatcher creates a new NotifyDispatcher, using the supplied
pq.Listener underneath.  The ownership of the Listener is transferred to
NotifyDispatcher.  You should not use it after calling NewNotifyDispatcher.
package notifydispatcher
import (
	"container/list"
	"errors"
	"fmt"
	"github.com/lib/pq"
	"sync"
)
var (
	ErrChannelAlreadyActive = errors.New("channel is already active")
	ErrChannelNotActive = errors.New("channel is not active")
)
var errClosed = errors.New("NotifyDispatcher has been closed")
type SlowReaderEliminationStrategy int
const (
	CloseSlowReaders SlowReaderEliminationStrategy = iota
	NeglectSlowReaders
)
type listenRequest struct {
	channel string
	unlisten bool
}
type BroadcastChannel struct {
	Channel chan struct{}
	elem *list.Element
}
type Listener interface {
	Listen(channel string) error
	Unlisten(channel string) error
	NotificationChannel() <-chan *pq.Notification
}
type NotifyDispatcher struct {
	listener Listener
	slowReaderEliminationStrategy SlowReaderEliminationStrategy
	broadcastOnConnectionLoss bool
	broadcastChannels *list.List
	listenRequestch chan listenRequest
	lock sync.Mutex
	channels map[string] *listenSet
	closed bool
	closeChannel chan bool
}