registry.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package registry
  15. import (
  16. "context"
  17. "reflect"
  18. "sort"
  19. )
  20. type Descriptor struct {
  21. Name string
  22. Instance Service
  23. InitPriority Priority
  24. }
  25. var services []*Descriptor
  26. func RegisterService(instance Service) {
  27. services = append(services, &Descriptor{
  28. Name: reflect.TypeOf(instance).Elem().Name(),
  29. Instance: instance,
  30. InitPriority: Low,
  31. })
  32. }
  33. func Register(descriptor *Descriptor) {
  34. services = append(services, descriptor)
  35. }
  36. func GetServices() []*Descriptor {
  37. slice := getServicesWithOverrides()
  38. sort.Slice(slice, func(i, j int) bool {
  39. return slice[i].InitPriority > slice[j].InitPriority
  40. })
  41. return slice
  42. }
  43. type OverrideServiceFunc func(descriptor Descriptor) (*Descriptor, bool)
  44. var overrides []OverrideServiceFunc
  45. func getServicesWithOverrides() []*Descriptor {
  46. slice := []*Descriptor{}
  47. for _, s := range services {
  48. var descriptor *Descriptor
  49. for _, fn := range overrides {
  50. if newDescriptor, override := fn(*s); override {
  51. descriptor = newDescriptor
  52. break
  53. }
  54. }
  55. if descriptor != nil {
  56. slice = append(slice, descriptor)
  57. } else {
  58. slice = append(slice, s)
  59. }
  60. }
  61. return slice
  62. }
  63. // Service interface is the lowest common shape that services
  64. // are expected to forfill to be started within monitor.
  65. type Service interface {
  66. // Init is called by monitor main process which gives the service
  67. // the possibility do some initial work before its started. Things
  68. // like adding routes, bus handlers should be done in the Init function
  69. Init() error
  70. }
  71. // CanBeDisabled allows the services to decide if it should
  72. // be started or not by itself. This is useful for services
  73. // that might not always be started, ex alerting.
  74. // This will be called after `Init()`.
  75. type CanBeDisabled interface {
  76. // IsDisabled should return a bool saying if it can be started or not.
  77. IsDisabled() bool
  78. }
  79. // BackgroundService should be implemented for services that have
  80. // long running tasks in the background.
  81. type BackgroundService interface {
  82. // Run starts the background process of the service after `Init` have been called
  83. // on all services. The `context.Context` passed into the function should be used
  84. // to subscribe to ctx.Done() so the service can be notified when monitor shuts down.
  85. Run(ctx context.Context) error
  86. }
  87. // IsDisabled takes an service and return true if its disabled
  88. func IsDisabled(srv Service) bool {
  89. canBeDisabled, ok := srv.(CanBeDisabled)
  90. return ok && canBeDisabled.IsDisabled()
  91. }
  92. type Priority int
  93. const (
  94. High Priority = 100
  95. Low Priority = 0
  96. )