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  }