package channels import ( "errors" "log" "sync" "github.com/cskr/pubsub" ) type ChannelManager struct { channels map[string]*Channel channelsLock sync.RWMutex pubsub *pubsub.PubSub } func NewChannelManager() *ChannelManager { mgr := &ChannelManager{ pubsub: pubsub.New(1), channels: map[string]*Channel{}, } return mgr } func (manager *ChannelManager) Events() *pubsub.PubSub { return manager.pubsub } func (manager *ChannelManager) Channel(uuid string) *Channel { manager.channelsLock.RLock() defer manager.channelsLock.RUnlock() channel, ok := manager.channels[uuid] if !ok { return nil } return channel } func (manager *ChannelManager) Close(uuid string) (err error) { manager.channelsLock.Lock() defer manager.channelsLock.Unlock() _, ok := manager.channels[uuid] if !ok { err = errors.New("channel uuid is not known") return } manager.pubsub.Pub(uuid, "close") delete(manager.channels, uuid) return } func (manager *ChannelManager) Open(uuid string) (channel *Channel, err error) { manager.channelsLock.Lock() defer manager.channelsLock.Unlock() if _, ok := manager.channels[uuid]; ok { err = errors.New("channel uuid is already in use") return } channel = NewChannel() manager.channels[uuid] = channel log.Println("Channel opened:", uuid) manager.pubsub.Pub(uuid, "open") return } func (manager *ChannelManager) Shutdown() { manager.pubsub.Shutdown() }