mirror of
https://github.com/stashapp/stash.git
synced 2025-12-10 10:22:18 +01:00
86 lines
1.6 KiB
Go
86 lines
1.6 KiB
Go
package events
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/markbates/safe"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type DeleteFn func()
|
|
|
|
// Manager can be implemented to replace the default
|
|
// events manager
|
|
type Manager interface {
|
|
Listen(string, Listener) (DeleteFn, error)
|
|
Emit(Event) error
|
|
}
|
|
|
|
// DefaultManager implements a map backed Manager
|
|
func DefaultManager() Manager {
|
|
return &manager{
|
|
listeners: listenerMap{},
|
|
}
|
|
}
|
|
|
|
// SetManager allows you to replace the default
|
|
// event manager with a custom one
|
|
func SetManager(m Manager) {
|
|
boss = m
|
|
}
|
|
|
|
var boss Manager = DefaultManager()
|
|
var _ listable = &manager{}
|
|
|
|
type manager struct {
|
|
listeners listenerMap
|
|
}
|
|
|
|
func (m *manager) Listen(name string, l Listener) (DeleteFn, error) {
|
|
_, ok := m.listeners.Load(name)
|
|
if ok {
|
|
return nil, errors.Errorf("listener named %s is already listening", name)
|
|
}
|
|
|
|
m.listeners.Store(name, l)
|
|
|
|
df := func() {
|
|
m.listeners.Delete(name)
|
|
}
|
|
|
|
return df, nil
|
|
}
|
|
|
|
func (m *manager) Emit(e Event) error {
|
|
if err := e.Validate(); err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
e.Kind = strings.ToLower(e.Kind)
|
|
if e.IsError() && e.Error == nil {
|
|
e.Error = errors.New(e.Kind)
|
|
}
|
|
go func(e Event) {
|
|
m.listeners.Range(func(key string, l Listener) bool {
|
|
ex := Event{
|
|
Kind: e.Kind,
|
|
Error: e.Error,
|
|
Message: e.Message,
|
|
Payload: Payload{},
|
|
}
|
|
for k, v := range e.Payload {
|
|
ex.Payload[k] = v
|
|
}
|
|
go func(e Event, l Listener) {
|
|
safe.Run(func() {
|
|
l(e)
|
|
})
|
|
}(ex, l)
|
|
return true
|
|
})
|
|
}(e)
|
|
return nil
|
|
}
|
|
|
|
func (m *manager) List() ([]string, error) {
|
|
return m.listeners.Keys(), nil
|
|
}
|