github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/worker/leadership/manifold.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package leadership 5 6 import ( 7 "fmt" 8 "time" 9 10 "github.com/juju/errors" 11 "github.com/juju/names" 12 13 "github.com/juju/juju/agent" 14 "github.com/juju/juju/api/base" 15 "github.com/juju/juju/api/leadership" 16 coreleadership "github.com/juju/juju/core/leadership" 17 "github.com/juju/juju/worker" 18 "github.com/juju/juju/worker/dependency" 19 ) 20 21 // ManifoldConfig defines the names of the manifolds on which a Manifold will depend. 22 type ManifoldConfig struct { 23 AgentName string 24 APICallerName string 25 LeadershipGuarantee time.Duration 26 } 27 28 // Manifold returns a manifold whose worker wraps a Tracker working on behalf of 29 // the dependency identified by AgentName. 30 func Manifold(config ManifoldConfig) dependency.Manifold { 31 return dependency.Manifold{ 32 Inputs: []string{ 33 config.AgentName, 34 config.APICallerName, 35 }, 36 Start: startFunc(config), 37 Output: outputFunc, 38 } 39 } 40 41 // startFunc returns a StartFunc that creates a worker based on the manifolds 42 // named in the supplied config. 43 func startFunc(config ManifoldConfig) dependency.StartFunc { 44 return func(context dependency.Context) (worker.Worker, error) { 45 var agent agent.Agent 46 if err := context.Get(config.AgentName, &agent); err != nil { 47 return nil, err 48 } 49 var apiCaller base.APICaller 50 if err := context.Get(config.APICallerName, &apiCaller); err != nil { 51 return nil, err 52 } 53 return NewManifoldWorker(agent, apiCaller, config.LeadershipGuarantee) 54 } 55 } 56 57 // NewManifoldWorker wraps NewTracker for the convenience of startFunc. It 58 // exists primarily to be patched out via NewManifoldWorker for ease of testing, 59 // and is not itself directly tested. It would almost certainly be better to 60 // pass the constructor dependencies in as explicit manifold config. 61 var NewManifoldWorker = func(agent agent.Agent, apiCaller base.APICaller, guarantee time.Duration) (worker.Worker, error) { 62 tag := agent.CurrentConfig().Tag() 63 unitTag, ok := tag.(names.UnitTag) 64 if !ok { 65 return nil, fmt.Errorf("expected a unit tag; got %q", tag) 66 } 67 claimer := leadership.NewClient(apiCaller) 68 return NewTracker(unitTag, claimer, guarantee), nil 69 } 70 71 // outputFunc extracts the coreleadership.Tracker from a *Tracker passed in as a Worker. 72 func outputFunc(in worker.Worker, out interface{}) error { 73 inWorker, _ := in.(*Tracker) 74 if inWorker == nil { 75 return errors.Errorf("expected *Tracker input; got %T", in) 76 } 77 outPointer, _ := out.(*coreleadership.Tracker) 78 if outPointer == nil { 79 return errors.Errorf("expected *leadership.Tracker output; got %T", out) 80 } 81 *outPointer = inWorker 82 return nil 83 }