package calendar import "sync" type ChatEventHub struct { mu sync.Mutex subscribers map[string]map[chan struct{}]struct{} } func NewChatEventHub() *ChatEventHub { return &ChatEventHub{ subscribers: map[string]map[chan struct{}]struct{}{}, } } func (h *ChatEventHub) Subscribe(itemID string, channel string) (chan struct{}, func()) { key := chatEventKey(itemID, channel) events := make(chan struct{}, 1) h.mu.Lock() if h.subscribers[key] == nil { h.subscribers[key] = map[chan struct{}]struct{}{} } h.subscribers[key][events] = struct{}{} h.mu.Unlock() return events, func() { h.mu.Lock() defer h.mu.Unlock() delete(h.subscribers[key], events) if len(h.subscribers[key]) == 0 { delete(h.subscribers, key) } close(events) } } func (h *ChatEventHub) Publish(itemID string, channel string) { key := chatEventKey(itemID, channel) h.mu.Lock() defer h.mu.Unlock() for events := range h.subscribers[key] { select { case events <- struct{}{}: default: } } } func chatEventKey(itemID string, channel string) string { return itemID + ":" + channel }