github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/singular/manifold.go (about) 1 // Copyright 2015-2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package singular 5 6 import ( 7 "time" 8 9 "github.com/juju/clock" 10 "github.com/juju/errors" 11 "gopkg.in/juju/names.v2" 12 "gopkg.in/juju/worker.v1" 13 "gopkg.in/juju/worker.v1/dependency" 14 15 "github.com/juju/juju/api/base" 16 "github.com/juju/juju/cmd/jujud/agent/engine" 17 ) 18 19 // ManifoldConfig holds the information necessary to run a FlagWorker in 20 // a dependency.Engine. 21 type ManifoldConfig struct { 22 ClockName string 23 APICallerName string 24 Duration time.Duration 25 Claimant names.MachineTag 26 Entity names.Tag 27 28 NewFacade func(base.APICaller, names.MachineTag, names.Tag) (Facade, error) 29 NewWorker func(FlagConfig) (worker.Worker, error) 30 } 31 32 // start is a method on ManifoldConfig because it's more readable than a closure. 33 func (config ManifoldConfig) start(context dependency.Context) (worker.Worker, error) { 34 var clock clock.Clock 35 if err := context.Get(config.ClockName, &clock); err != nil { 36 return nil, errors.Trace(err) 37 } 38 var apiCaller base.APICaller 39 if err := context.Get(config.APICallerName, &apiCaller); err != nil { 40 return nil, errors.Trace(err) 41 } 42 43 facade, err := config.NewFacade(apiCaller, config.Claimant, config.Entity) 44 if err != nil { 45 return nil, errors.Trace(err) 46 } 47 flag, err := config.NewWorker(FlagConfig{ 48 Clock: clock, 49 Facade: facade, 50 Duration: config.Duration, 51 }) 52 if err != nil { 53 return nil, errors.Trace(err) 54 } 55 return wrappedWorker{flag}, nil 56 } 57 58 // wrappedWorker wraps a flag worker, translating ErrRefresh into 59 // dependency.ErrBounce. 60 type wrappedWorker struct { 61 worker.Worker 62 } 63 64 // Wait is part of the worker.Worker interface. 65 func (w wrappedWorker) Wait() error { 66 err := w.Worker.Wait() 67 if err == ErrRefresh { 68 err = dependency.ErrBounce 69 } 70 return err 71 } 72 73 // Manifold returns a dependency.Manifold that will run a FlagWorker and 74 // expose it to clients as a engine.Flag resource. 75 func Manifold(config ManifoldConfig) dependency.Manifold { 76 return dependency.Manifold{ 77 Inputs: []string{ 78 config.ClockName, 79 config.APICallerName, 80 }, 81 Start: config.start, 82 Output: func(in worker.Worker, out interface{}) error { 83 if w, ok := in.(wrappedWorker); ok { 84 in = w.Worker 85 } 86 return engine.FlagOutput(in, out) 87 }, 88 } 89 }