github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/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 "github.com/juju/juju/worker" 17 "github.com/juju/juju/worker/dependency" 18 ) 19 20 // ManifoldConfig defines the names of the manifolds on which a Manifold will depend. 21 type ManifoldConfig struct { 22 AgentName string 23 APICallerName string 24 LeadershipGuarantee time.Duration 25 } 26 27 // Manifold returns a manifold whose worker wraps a Tracker working on behalf of 28 // the dependency identified by AgentName. 29 func Manifold(config ManifoldConfig) dependency.Manifold { 30 return dependency.Manifold{ 31 Inputs: []string{ 32 config.AgentName, 33 config.APICallerName, 34 }, 35 Start: startFunc(config), 36 Output: outputFunc, 37 } 38 } 39 40 // startFunc returns a StartFunc that creates a worker based on the manifolds 41 // named in the supplied config. 42 func startFunc(config ManifoldConfig) dependency.StartFunc { 43 return func(getResource dependency.GetResourceFunc) (worker.Worker, error) { 44 var agent agent.Agent 45 if err := getResource(config.AgentName, &agent); err != nil { 46 return nil, err 47 } 48 var apiCaller base.APICaller 49 if err := getResource(config.APICallerName, &apiCaller); err != nil { 50 return nil, err 51 } 52 return newManifoldWorker(agent, apiCaller, config.LeadershipGuarantee) 53 } 54 } 55 56 // newManifoldWorker wraps NewTrackerWorker for the convenience of startFunc. It 57 // exists primarily to be patched out via NewManifoldWorker for ease of testing, 58 // and is not itself directly tested; once all NewTrackerWorker clients have been 59 // replaced with manifolds, the tests can be tidied up a bit. 60 var newManifoldWorker = func(agent agent.Agent, apiCaller base.APICaller, guarantee time.Duration) (worker.Worker, error) { 61 tag := agent.CurrentConfig().Tag() 62 unitTag, ok := tag.(names.UnitTag) 63 if !ok { 64 return nil, fmt.Errorf("expected a unit tag; got %q", tag) 65 } 66 claimer := leadership.NewClient(apiCaller) 67 return NewTrackerWorker(unitTag, claimer, guarantee), nil 68 } 69 70 // outputFunc extracts the Tracker from a *tracker passed in as a Worker. 71 func outputFunc(in worker.Worker, out interface{}) error { 72 inWorker, _ := in.(*tracker) 73 outPointer, _ := out.(*Tracker) 74 if inWorker == nil || outPointer == nil { 75 return errors.Errorf("expected %T->%T; got %T->%T", inWorker, outPointer, in, out) 76 } 77 *outPointer = inWorker 78 return nil 79 }