github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/modelcache/manifold.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package modelcache 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/prometheus/client_golang/prometheus" 9 "gopkg.in/juju/worker.v1" 10 "gopkg.in/juju/worker.v1/dependency" 11 12 "github.com/juju/juju/core/cache" 13 workerstate "github.com/juju/juju/worker/state" 14 ) 15 16 // Logger describes the logging methods used in this package by the worker. 17 type Logger interface { 18 IsTraceEnabled() bool 19 Tracef(string, ...interface{}) 20 Errorf(string, ...interface{}) 21 } 22 23 // ManifoldConfig holds the information necessary to run a model cache worker in 24 // a dependency.Engine. 25 type ManifoldConfig struct { 26 StateName string 27 Logger Logger 28 29 PrometheusRegisterer prometheus.Registerer 30 31 NewWorker func(Config) (worker.Worker, error) 32 } 33 34 // Validate validates the manifold configuration. 35 func (config ManifoldConfig) Validate() error { 36 if config.StateName == "" { 37 return errors.NotValidf("empty StateName") 38 } 39 if config.Logger == nil { 40 return errors.NotValidf("missing Logger") 41 } 42 if config.PrometheusRegisterer == nil { 43 return errors.NotValidf("missing PrometheusRegisterer") 44 } 45 if config.NewWorker == nil { 46 return errors.NotValidf("missing NewWorker func") 47 } 48 return nil 49 } 50 51 // Manifold returns a dependency.Manifold that will run a model cache 52 // worker. The manifold outputs a *cache.Controller, primarily for 53 // the apiserver to depend on and use. 54 func Manifold(config ManifoldConfig) dependency.Manifold { 55 return dependency.Manifold{ 56 Inputs: []string{ 57 config.StateName, 58 }, 59 Start: config.start, 60 Output: ExtractCacheController, 61 } 62 } 63 64 // start is a method on ManifoldConfig because it's more readable than a closure. 65 func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) { 66 if err := config.Validate(); err != nil { 67 return nil, errors.Trace(err) 68 } 69 70 var stTracker workerstate.StateTracker 71 if err := context.Get(config.StateName, &stTracker); err != nil { 72 return nil, errors.Trace(err) 73 } 74 75 statePool, err := stTracker.Use() 76 if err != nil { 77 return nil, errors.Trace(err) 78 } 79 80 w, err := config.NewWorker(Config{ 81 Logger: config.Logger, 82 StatePool: statePool, 83 PrometheusRegisterer: config.PrometheusRegisterer, 84 Cleanup: func() { 85 stTracker.Done() 86 }, 87 }) 88 if err != nil { 89 stTracker.Done() 90 return nil, errors.Trace(err) 91 } 92 return w, nil 93 } 94 95 // ExtractCacheController extracts a *cache.Controller from a *cacheWorker. 96 func ExtractCacheController(in worker.Worker, out interface{}) error { 97 inWorker, _ := in.(*cacheWorker) 98 if inWorker == nil { 99 return errors.Errorf("in should be a %T; got %T", inWorker, in) 100 } 101 102 switch outPointer := out.(type) { 103 case **cache.Controller: 104 *outPointer = inWorker.controller 105 default: 106 return errors.Errorf("out should be *cache.Controller; got %T", out) 107 } 108 return nil 109 }