github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/worker/agent/manifold.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package agent 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/names" 9 "launchpad.net/tomb" 10 11 "github.com/juju/juju/agent" 12 "github.com/juju/juju/network" 13 "github.com/juju/juju/worker" 14 "github.com/juju/juju/worker/dependency" 15 ) 16 17 // Agent is the interface exposed to workers that depend upon an agent's 18 // representation in its dependency.Engine. 19 // TODO(fwereade) this could *surely* be cleaned up, I'm not at all convinced 20 // these all need to go together: in particular, can't we accomplish the same 21 // function as SetAPIHostPorts with ChangeConfig? 22 type Agent interface { 23 Tag() names.Tag 24 CurrentConfig() agent.Config 25 ChangeConfig(agent.ConfigMutator) error 26 SetAPIHostPorts([][]network.HostPort) error 27 } 28 29 // Manifold returns a manifold that starts a worker proxying the supplied Agent 30 // for use by other workers. 31 func Manifold(agent Agent) dependency.Manifold { 32 return dependency.Manifold{ 33 Start: startFunc(agent), 34 Output: outputFunc, 35 } 36 } 37 38 // startFunc returns a StartFunc that starts a worker holding a reference to 39 // the supplied Agent. 40 func startFunc(agent Agent) dependency.StartFunc { 41 return func(_ dependency.GetResourceFunc) (worker.Worker, error) { 42 w := &agentWorker{agent: agent} 43 go func() { 44 defer w.tomb.Done() 45 <-w.tomb.Dying() 46 }() 47 return w, nil 48 } 49 } 50 51 // outputFunc extracts an Agent from its *agentWorker. 52 func outputFunc(in worker.Worker, out interface{}) error { 53 inWorker, _ := in.(*agentWorker) 54 outPointer, _ := out.(*Agent) 55 if inWorker == nil || outPointer == nil { 56 return errors.Errorf("expected %T->%T; got %T->%T", inWorker, outPointer, in, out) 57 } 58 *outPointer = inWorker.agent 59 return nil 60 } 61 62 // agentWorker is a degenerate worker.Worker that exists only to make an Agent 63 // accessible via the manifold's Output. 64 type agentWorker struct { 65 tomb tomb.Tomb 66 agent Agent 67 } 68 69 // Kill is part of the worker.Worker interface. 70 func (w *agentWorker) Kill() { 71 w.tomb.Kill(nil) 72 } 73 74 // Wait is part of the worker.Worker interface. 75 func (w *agentWorker) Wait() error { 76 return w.tomb.Wait() 77 }