github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/api/leadership/client.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  /*
     5  Package leadership implements the client to the analog leadership
     6  service.
     7  */
     8  package leadership
     9  
    10  import (
    11  	"time"
    12  
    13  	"github.com/juju/errors"
    14  	"github.com/juju/loggo"
    15  	"github.com/juju/names"
    16  
    17  	"github.com/juju/juju/api/base"
    18  	"github.com/juju/juju/apiserver/params"
    19  	"github.com/juju/juju/leadership"
    20  )
    21  
    22  var logger = loggo.GetLogger("juju.api.leadership")
    23  
    24  type client struct {
    25  	base.FacadeCaller
    26  }
    27  
    28  // NewClient returns a new leadership.Claimer backed by the supplied api caller.
    29  func NewClient(caller base.APICaller) leadership.Claimer {
    30  	return &client{base.NewFacadeCaller(caller, "LeadershipService")}
    31  }
    32  
    33  // ClaimLeadership is part of the leadership.Claimer interface.
    34  func (c *client) ClaimLeadership(serviceId, unitId string, duration time.Duration) error {
    35  
    36  	results, err := c.bulkClaimLeadership(c.prepareClaimLeadership(serviceId, unitId, duration))
    37  	if err != nil {
    38  		return err
    39  	}
    40  
    41  	// TODO(fwereade): this is not a rightful panic; we don't know who'll be using
    42  	// this client, and/or whether or not we're running critical code in the same
    43  	// process.
    44  	if err := results.Results[0].Error; err != nil {
    45  		if params.IsCodeLeadershipClaimDenied(err) {
    46  			return leadership.ErrClaimDenied
    47  		}
    48  		return err
    49  	}
    50  	return nil
    51  }
    52  
    53  // BlockUntilLeadershipReleased is part of the leadership.Claimer interface.
    54  func (c *client) BlockUntilLeadershipReleased(serviceId string) error {
    55  	const friendlyErrMsg = "error blocking on leadership release"
    56  	var result params.ErrorResult
    57  	err := c.FacadeCall("BlockUntilLeadershipReleased", names.NewServiceTag(serviceId), &result)
    58  	if err != nil {
    59  		return errors.Annotate(err, friendlyErrMsg)
    60  	} else if result.Error != nil {
    61  		return errors.Annotate(result.Error, friendlyErrMsg)
    62  	}
    63  	return nil
    64  }
    65  
    66  //
    67  // Prepare functions for building bulk-calls.
    68  //
    69  
    70  // prepareClaimLeadership creates a single set of params in
    71  // preperation for making a bulk call.
    72  func (c *client) prepareClaimLeadership(serviceId, unitId string, duration time.Duration) params.ClaimLeadershipParams {
    73  	return params.ClaimLeadershipParams{
    74  		names.NewServiceTag(serviceId).String(),
    75  		names.NewUnitTag(unitId).String(),
    76  		duration.Seconds(),
    77  	}
    78  }
    79  
    80  //
    81  // Bulk calls.
    82  //
    83  
    84  func (c *client) bulkClaimLeadership(args ...params.ClaimLeadershipParams) (*params.ClaimLeadershipBulkResults, error) {
    85  	// Don't make the jump over the network if we don't have to.
    86  	if len(args) <= 0 {
    87  		return &params.ClaimLeadershipBulkResults{}, nil
    88  	}
    89  
    90  	bulkParams := params.ClaimLeadershipBulkParams{args}
    91  	var results params.ClaimLeadershipBulkResults
    92  	if err := c.FacadeCall("ClaimLeadership", bulkParams, &results); err != nil {
    93  		return nil, errors.Annotate(err, "error making a leadership claim")
    94  	}
    95  	return &results, nil
    96  }