github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/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 LeadershipManager backed by the supplied api caller. 29 func NewClient(caller base.APICaller) leadership.LeadershipManager { 30 return &client{base.NewFacadeCaller(caller, "LeadershipService")} 31 } 32 33 // ClaimLeadership implements LeadershipManager. 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 // ReleaseLeadership implements LeadershipManager. 54 func (c *client) ReleaseLeadership(serviceId, unitId string) error { 55 results, err := c.bulkReleaseLeadership(c.prepareReleaseLeadership(serviceId, unitId)) 56 if err != nil { 57 return err 58 } 59 60 // TODO(fwereade): this is not a rightful panic; we don't know who'll be using 61 // this client, and/or whether or not we're running critical code in the same 62 // process. 63 if err := results.Results[0].Error; err != nil { 64 return err 65 } 66 return nil 67 } 68 69 // BlockUntilLeadershipReleased implements LeadershipManager. 70 func (c *client) BlockUntilLeadershipReleased(serviceId string) error { 71 const friendlyErrMsg = "error blocking on leadership release" 72 var result params.ErrorResult 73 err := c.FacadeCall("BlockUntilLeadershipReleased", names.NewServiceTag(serviceId), &result) 74 if err != nil { 75 return errors.Annotate(err, friendlyErrMsg) 76 } else if result.Error != nil { 77 return errors.Annotate(result.Error, friendlyErrMsg) 78 } 79 return nil 80 } 81 82 // 83 // Prepare functions for building bulk-calls. 84 // 85 86 // prepareClaimLeadership creates a single set of params in 87 // preperation for making a bulk call. 88 func (c *client) prepareClaimLeadership(serviceId, unitId string, duration time.Duration) params.ClaimLeadershipParams { 89 return params.ClaimLeadershipParams{ 90 names.NewServiceTag(serviceId).String(), 91 names.NewUnitTag(unitId).String(), 92 duration.Seconds(), 93 } 94 } 95 96 // prepareReleaseLeadership creates a single set of params in 97 // preperation for making a bulk call. 98 func (c *client) prepareReleaseLeadership(serviceId, unitId string) params.ReleaseLeadershipParams { 99 return params.ReleaseLeadershipParams{ 100 names.NewServiceTag(serviceId).String(), 101 names.NewUnitTag(unitId).String(), 102 } 103 } 104 105 // 106 // Bulk calls. 107 // 108 109 func (c *client) bulkClaimLeadership(args ...params.ClaimLeadershipParams) (*params.ClaimLeadershipBulkResults, error) { 110 // Don't make the jump over the network if we don't have to. 111 if len(args) <= 0 { 112 return ¶ms.ClaimLeadershipBulkResults{}, nil 113 } 114 115 bulkParams := params.ClaimLeadershipBulkParams{args} 116 var results params.ClaimLeadershipBulkResults 117 if err := c.FacadeCall("ClaimLeadership", bulkParams, &results); err != nil { 118 return nil, errors.Annotate(err, "error making a leadership claim") 119 } 120 return &results, nil 121 } 122 123 func (c *client) bulkReleaseLeadership(args ...params.ReleaseLeadershipParams) (*params.ReleaseLeadershipBulkResults, error) { 124 // Don't make the jump over the network if we don't have to. 125 if len(args) <= 0 { 126 return ¶ms.ReleaseLeadershipBulkResults{}, nil 127 } 128 129 bulkParams := params.ReleaseLeadershipBulkParams{args} 130 var results params.ReleaseLeadershipBulkResults 131 if err := c.FacadeCall("ReleaseLeadership", bulkParams, &results); err != nil { 132 return nil, errors.Annotate(err, "cannot release leadership") 133 } 134 135 return &results, nil 136 }