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  }