mirror of
https://github.com/sot-tech/mochi.git
synced 2026-04-27 08:00:00 -07:00
67 lines
1.7 KiB
Go
67 lines
1.7 KiB
Go
// Package middleware implements the Logic interface by executing
|
|
// a series of middleware hooks.
|
|
package middleware
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/sot-tech/mochi/pkg/conf"
|
|
"github.com/sot-tech/mochi/pkg/log"
|
|
"github.com/sot-tech/mochi/storage"
|
|
)
|
|
|
|
var (
|
|
logger = log.NewLogger("middleware")
|
|
buildersMU sync.RWMutex
|
|
builders = make(map[string]Builder)
|
|
)
|
|
|
|
// Builder is the function used to initialize a new Hook
|
|
// with provided configuration.
|
|
type Builder func(conf.MapConfig, storage.PeerStorage) (Hook, error)
|
|
|
|
// RegisterBuilder makes a Builder available by the provided name.
|
|
//
|
|
// If called twice with the same name, the name is blank, or if the provided
|
|
// Builder is nil, this function panics.
|
|
func RegisterBuilder(name string, b Builder) {
|
|
if name == "" {
|
|
panic("middleware: could not register Builder with an empty name")
|
|
}
|
|
if b == nil {
|
|
panic("middleware: could not register a nil Builder")
|
|
}
|
|
|
|
buildersMU.Lock()
|
|
defer buildersMU.Unlock()
|
|
|
|
if _, dup := builders[name]; dup {
|
|
panic("middleware: RegisterBuilder called twice for " + name)
|
|
}
|
|
|
|
builders[name] = b
|
|
}
|
|
|
|
// NewHooks is a utility function for initializing Hooks in bulk.
|
|
func NewHooks(configs []conf.NamedMapConfig, storage storage.PeerStorage) (hooks []Hook, err error) {
|
|
buildersMU.RLock()
|
|
defer buildersMU.RUnlock()
|
|
for _, c := range configs {
|
|
logger.Debug().Object("hook", c).Msg("starting hook")
|
|
newHook, ok := builders[c.Name]
|
|
if !ok {
|
|
err = fmt.Errorf("hook with name '%s' does not exists", c.Name)
|
|
break
|
|
}
|
|
var h Hook
|
|
if h, err = newHook(c.Config, storage); err != nil {
|
|
break
|
|
}
|
|
hooks = append(hooks, h)
|
|
logger.Info().Str("name", c.Name).Msg("hook started")
|
|
}
|
|
|
|
return
|
|
}
|