Skip to content

Instantly share code, notes, and snippets.

@tommy-muehle
Last active October 27, 2019 15:10
Show Gist options
  • Save tommy-muehle/cc8c4301c7ce65e7ac53ae83787cdb4d to your computer and use it in GitHub Desktop.
Save tommy-muehle/cc8c4301c7ce65e7ac53ae83787cdb4d to your computer and use it in GitHub Desktop.
Event dispatcher
package events
import (
"sync"
"context"
)
type Dispatcher struct {
mutex *sync.RWMutex
listeners map[string][]Listener
}
func NewDispatcher() *Dispatcher {
return &Dispatcher{
listeners: make(map[string][]Listener),
mutex: new(sync.RWMutex),
}
}
func (this *Dispatcher) AddListener(on string, listener Listener) {
this.mutex.Lock()
defer this.mutex.Unlock()
this.listeners[on] = append(this.listeners[on], listener)
}
func (this *Dispatcher) Dispatch(ctx context.Context, event Event) error {
listeners, ok := this.listeners[event.GetKey()]
if !ok {
return nil
}
var wg sync.WaitGroup
wg.Add(len(listeners))
errChannel := make(chan error, 1)
done := make(chan bool, 1)
for _, listener := range listeners {
go func() {
defer wg.Done()
if err := listener.Execute(ctx, event); err != nil {
errChannel <- err
}
}()
}
go func() {
wg.Wait()
close(done)
}()
select {
case <-done:
case err := <-errChannel:
return err
}
return nil
}
package events
type Event interface {
GetKey() string
}
package events
import (
"context"
)
type Listener interface {
Execute(ctx context.Context, event Event) error
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment