tracker/middleware/middleware.go

95 lines
2.3 KiB
Go
Raw Normal View History

2016-08-10 02:08:15 +02:00
// Package middleware implements the TrackerLogic interface by executing
// a series of middleware hooks.
package middleware
import (
2017-12-23 20:54:51 +01:00
"errors"
"sync"
yaml "gopkg.in/yaml.v2"
2016-08-10 02:08:15 +02:00
)
2017-12-23 20:54:51 +01:00
var (
driversM sync.RWMutex
drivers = make(map[string]Driver)
2016-08-10 02:08:15 +02:00
2017-12-23 20:54:51 +01:00
// ErrDriverDoesNotExist is the error returned by NewMiddleware when a
// middleware driver with that name does not exist.
ErrDriverDoesNotExist = errors.New("middleware driver with that name does not exist")
)
2016-08-10 02:08:15 +02:00
2017-12-23 20:54:51 +01:00
// Driver is the interface used to initialize a new type of middleware.
//
// The options parameter is YAML encoded bytes that should be unmarshalled into
// the hook's custom configuration.
type Driver interface {
NewHook(options []byte) (Hook, error)
2016-08-10 02:08:15 +02:00
}
2017-12-23 20:54:51 +01:00
// RegisterDriver makes a Driver available by the provided name.
//
// If called twice with the same name, the name is blank, or if the provided
// Driver is nil, this function panics.
func RegisterDriver(name string, d Driver) {
if name == "" {
panic("middleware: could not register a Driver with an empty name")
2016-08-10 02:08:15 +02:00
}
2017-12-23 20:54:51 +01:00
if d == nil {
panic("middleware: could not register a nil Driver")
2016-08-10 02:08:15 +02:00
}
2017-12-23 20:54:51 +01:00
driversM.Lock()
defer driversM.Unlock()
2016-08-10 02:08:15 +02:00
2017-12-23 20:54:51 +01:00
if _, dup := drivers[name]; dup {
panic("middleware: RegisterDriver called twice for " + name)
2016-08-10 02:08:15 +02:00
}
2017-12-23 20:54:51 +01:00
drivers[name] = d
2016-08-10 02:08:15 +02:00
}
2017-12-23 20:54:51 +01:00
// New attempts to initialize a new middleware instance from the
// list of registered Drivers.
//
// If a driver does not exist, returns ErrDriverDoesNotExist.
func New(name string, optionBytes []byte) (Hook, error) {
driversM.RLock()
defer driversM.RUnlock()
var d Driver
d, ok := drivers[name]
if !ok {
return nil, ErrDriverDoesNotExist
2016-08-10 02:08:15 +02:00
}
2017-12-23 20:54:51 +01:00
return d.NewHook(optionBytes)
2016-08-10 02:08:15 +02:00
}
2017-12-23 20:54:51 +01:00
// HookConfig is the generic configuration format used for all registered Hooks.
type HookConfig struct {
Name string `yaml:"name"`
Options map[string]interface{} `yaml:"options"`
2016-08-10 02:08:15 +02:00
}
2016-09-24 19:38:05 +02:00
2017-12-23 20:54:51 +01:00
// HooksFromHookConfigs is a utility function for initializing Hooks in bulk.
func HooksFromHookConfigs(cfgs []HookConfig) (hooks []Hook, err error) {
for _, cfg := range cfgs {
// Marshal the options back into bytes.
var optionBytes []byte
optionBytes, err = yaml.Marshal(cfg.Options)
if err != nil {
return
2016-09-24 19:38:05 +02:00
}
2017-12-23 20:54:51 +01:00
var h Hook
h, err = New(cfg.Name, optionBytes)
if err != nil {
return
2016-09-24 19:38:05 +02:00
}
2017-12-23 20:54:51 +01:00
hooks = append(hooks, h)
2016-09-24 19:38:05 +02:00
}
2017-12-23 20:54:51 +01:00
return
2016-09-24 19:38:05 +02:00
}