mirror of
https://github.com/grafana/grafana.git
synced 2024-11-29 20:24:18 -06:00
25048ebdf8
* CloudWatch: Add HTTP API tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
154 lines
3.6 KiB
Go
154 lines
3.6 KiB
Go
package registry
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"sort"
|
|
|
|
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
|
)
|
|
|
|
type Descriptor struct {
|
|
Name string
|
|
Instance Service
|
|
InitPriority Priority
|
|
}
|
|
|
|
var services []*Descriptor
|
|
|
|
func RegisterServiceWithPriority(instance Service, priority Priority) {
|
|
Register(&Descriptor{
|
|
Name: reflect.TypeOf(instance).Elem().Name(),
|
|
Instance: instance,
|
|
InitPriority: priority,
|
|
})
|
|
}
|
|
|
|
func RegisterService(instance Service) {
|
|
Register(&Descriptor{
|
|
Name: reflect.TypeOf(instance).Elem().Name(),
|
|
Instance: instance,
|
|
InitPriority: Medium,
|
|
})
|
|
}
|
|
|
|
func Register(descriptor *Descriptor) {
|
|
if descriptor == nil {
|
|
return
|
|
}
|
|
// Overwrite any existing equivalent service
|
|
for i, svc := range services {
|
|
if svc.Name == descriptor.Name {
|
|
services[i] = descriptor
|
|
return
|
|
}
|
|
}
|
|
|
|
services = append(services, descriptor)
|
|
}
|
|
|
|
// GetService gets the registered service descriptor with a certain name.
|
|
// If none is found, nil is returned.
|
|
func GetService(name string) *Descriptor {
|
|
for _, svc := range services {
|
|
if svc.Name == name {
|
|
return svc
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetServices() []*Descriptor {
|
|
slice := getServicesWithOverrides()
|
|
|
|
sort.Slice(slice, func(i, j int) bool {
|
|
return slice[i].InitPriority > slice[j].InitPriority
|
|
})
|
|
|
|
return slice
|
|
}
|
|
|
|
type OverrideServiceFunc func(descriptor Descriptor) (*Descriptor, bool)
|
|
|
|
var overrides []OverrideServiceFunc
|
|
|
|
func RegisterOverride(fn OverrideServiceFunc) {
|
|
overrides = append(overrides, fn)
|
|
}
|
|
|
|
func ClearOverrides() {
|
|
overrides = nil
|
|
}
|
|
|
|
func getServicesWithOverrides() []*Descriptor {
|
|
slice := []*Descriptor{}
|
|
for _, s := range services {
|
|
var descriptor *Descriptor
|
|
for _, fn := range overrides {
|
|
if newDescriptor, override := fn(*s); override {
|
|
descriptor = newDescriptor
|
|
break
|
|
}
|
|
}
|
|
|
|
if descriptor != nil {
|
|
slice = append(slice, descriptor)
|
|
} else {
|
|
slice = append(slice, s)
|
|
}
|
|
}
|
|
|
|
return slice
|
|
}
|
|
|
|
// Service interface is the lowest common shape that services
|
|
// are expected to fulfill to be started within Grafana.
|
|
type Service interface {
|
|
// Init is called by Grafana main process which gives the service
|
|
// the possibility do some initial work before its started. Things
|
|
// like adding routes, bus handlers should be done in the Init function
|
|
Init() error
|
|
}
|
|
|
|
// CanBeDisabled allows the services to decide if it should
|
|
// be started or not by itself. This is useful for services
|
|
// that might not always be started, ex alerting.
|
|
// This will be called after `Init()`.
|
|
type CanBeDisabled interface {
|
|
// IsDisabled should return a bool saying if it can be started or not.
|
|
IsDisabled() bool
|
|
}
|
|
|
|
// BackgroundService should be implemented for services that have
|
|
// long running tasks in the background.
|
|
type BackgroundService interface {
|
|
// Run starts the background process of the service after `Init` have been called
|
|
// on all services. The `context.Context` passed into the function should be used
|
|
// to subscribe to ctx.Done() so the service can be notified when Grafana shuts down.
|
|
Run(ctx context.Context) error
|
|
}
|
|
|
|
// DatabaseMigrator allows the caller to add migrations to
|
|
// the migrator passed as argument
|
|
type DatabaseMigrator interface {
|
|
// AddMigrations allows the service to add migrations to
|
|
// the database migrator.
|
|
AddMigration(mg *migrator.Migrator)
|
|
}
|
|
|
|
// IsDisabled returns whether a service is disabled.
|
|
func IsDisabled(srv Service) bool {
|
|
canBeDisabled, ok := srv.(CanBeDisabled)
|
|
return ok && canBeDisabled.IsDisabled()
|
|
}
|
|
|
|
type Priority int
|
|
|
|
const (
|
|
High Priority = 100
|
|
MediumHigh Priority = 75
|
|
Medium Priority = 50
|
|
Low Priority = 0
|
|
)
|