github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/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/api/base"
    14  	"github.com/juju/juju/api/leadership"
    15  	"github.com/juju/juju/worker"
    16  	"github.com/juju/juju/worker/agent"
    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  	unitTag, ok := agent.Tag().(names.UnitTag)
    62  	if !ok {
    63  		return nil, fmt.Errorf("expected a unit tag; got %q", agent.Tag())
    64  	}
    65  	leadershipManager := leadership.NewClient(apiCaller)
    66  	return NewTrackerWorker(unitTag, leadershipManager, guarantee), nil
    67  }
    68  
    69  // outputFunc extracts the Tracker from a *tracker passed in as a Worker.
    70  func outputFunc(in worker.Worker, out interface{}) error {
    71  	inWorker, _ := in.(*tracker)
    72  	outPointer, _ := out.(*Tracker)
    73  	if inWorker == nil || outPointer == nil {
    74  		return errors.Errorf("expected %T->%T; got %T->%T", inWorker, outPointer, in, out)
    75  	}
    76  	*outPointer = inWorker
    77  	return nil
    78  }