summaryrefslogtreecommitdiff
path: root/service/registry.go
diff options
context:
space:
mode:
authorWolfy-J <[email protected]>2018-06-05 16:23:14 +0300
committerWolfy-J <[email protected]>2018-06-05 16:23:14 +0300
commit76ff8d1c95e087749d559ee5a4f8f0348feafffa (patch)
tree112630d2d2cfe41d809065034c13b1066b8e05c2 /service/registry.go
parent3c86132f90ef6473b4073a8b1500d01b6114fc30 (diff)
Cs and refactoring
Diffstat (limited to 'service/registry.go')
-rw-r--r--service/registry.go162
1 files changed, 162 insertions, 0 deletions
diff --git a/service/registry.go b/service/registry.go
new file mode 100644
index 00000000..d4e2ff12
--- /dev/null
+++ b/service/registry.go
@@ -0,0 +1,162 @@
+package service
+
+import (
+ "fmt"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+ "sync"
+)
+
+// Config provides ability to slice configuration sections and unmarshal configuration data into
+// given structure.
+type Config interface {
+ // Get nested config section (sub-map), returns nil if section not found.
+ Get(service string) Config
+
+ // Unmarshal unmarshal config data into given struct.
+ Unmarshal(out interface{}) error
+}
+
+// Registry controls all internal RR services and provides plugin based system.
+type Registry interface {
+ // Register add new service to the registry under given name.
+ Register(name string, service Service)
+
+ // Configure configures all underlying services with given configuration.
+ Configure(cfg Config) error
+
+ // Check is Service has been registered and configured.
+ Has(service string) bool
+
+ // Get returns Service instance by it's Name or nil if Service not found. Method must return only configured instance.
+ Get(service string) Service
+
+ // Serve all configured services. Non blocking.
+ Serve() error
+
+ // Stop all active services.
+ Stop() error
+}
+
+// Service provides high level functionality for road runner Service.
+type Service interface {
+ // WithConfig must return Service instance configured with the given environment. Must return error in case of
+ // misconfiguration, might return nil as Service if Service is not enabled.
+ WithConfig(cfg Config, reg Registry) (Service, error)
+
+ // Serve serves Service.
+ Serve() error
+
+ // Stop stop Service Service.
+ Stop() error
+}
+
+type registry struct {
+ log logrus.FieldLogger
+ mu sync.Mutex
+ candidates []*entry
+ configured []*entry
+}
+
+// entry creates association between service instance and given name.
+type entry struct {
+ // Associated service name
+ Name string
+
+ // Associated service instance
+ Service Service
+
+ // Serving indicates that service is currently serving
+ Serving bool
+}
+
+// NewRegistry creates new registry.
+func NewRegistry(log logrus.FieldLogger) Registry {
+ return &registry{
+ log: log,
+ candidates: make([]*entry, 0),
+ }
+}
+
+// Register add new service to the registry under given name.
+func (r *registry) Register(name string, service Service) {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+
+ r.candidates = append(r.candidates, &entry{
+ Name: name,
+ Service: service,
+ Serving: false,
+ })
+
+ r.log.Debugf("%s.service: registered", name)
+}
+
+// Configure configures all underlying services with given configuration.
+func (r *registry) Configure(cfg Config) error {
+ if r.configured != nil {
+ return fmt.Errorf("service bus has been already configured")
+ }
+
+ r.configured = make([]*entry, 0)
+ for _, e := range r.candidates {
+ segment := cfg.Get(e.Name)
+ if segment == nil {
+ r.log.Debugf("%s.service: no config has been provided", e.Name)
+ continue
+ }
+
+ s, err := e.Service.WithConfig(segment, r)
+ if err != nil {
+ return errors.Wrap(err, fmt.Sprintf("%s.service", e.Name))
+ }
+
+ if s != nil {
+ r.configured = append(r.configured, &entry{
+ Name: e.Name,
+ Service: s,
+ Serving: false,
+ })
+ }
+ }
+
+ return nil
+}
+
+// Check is Service has been registered.
+func (r *registry) Has(service string) bool {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+
+ for _, e := range r.configured {
+ if e.Name == service {
+ return true
+ }
+ }
+
+ return false
+}
+
+// Get returns Service instance by it's Name or nil if Service not found.
+func (r *registry) Get(service string) Service {
+ r.mu.Lock()
+ defer r.mu.Unlock()
+
+ for _, e := range r.configured {
+ if e.Name == service {
+ return e.Service
+ }
+ }
+
+ return nil
+}
+
+// Serve all configured services. Non blocking.
+func (r *registry) Serve() error {
+ return nil
+}
+
+// Stop all active services.
+func (r *registry) Stop() error {
+ return nil
+}