package events import ( "sync" "github.com/google/uuid" ) type IEventHandler interface { Publish(event IEvent) error Subscribe(event EventType, handle func(event IEvent)) ISubscription } func NewEventHandler() IEventHandler { handler := &eventHandler{ subscribers: make(map[EventType]map[string]func(IEvent)), mu: sync.Mutex{}, } return handler } type eventHandler struct { subscribers map[EventType]map[string]func(IEvent) mu sync.Mutex } func (handler *eventHandler) Publish(event IEvent) error { for eventType, handles := range handler.subscribers { if event.Typ() == eventType { for _, handle := range handles { handle(event) } } } return nil } func (handler *eventHandler) Subscribe(eventType EventType, handle func(event IEvent)) ISubscription { handler.mu.Lock() defer handler.mu.Unlock() id := uuid.NewString() if handler.subscribers[eventType] == nil { handler.subscribers[eventType] = make(map[string]func(IEvent)) } handler.subscribers[eventType][id] = handle return newSubscription(func() { handler.mu.Lock() defer handler.mu.Unlock() delete(handler.subscribers[eventType], id) if len(handler.subscribers[eventType]) < 1 { delete(handler.subscribers, eventType) } }) }