github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/state/leadership/claim.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 "time" 8 9 "github.com/juju/errors" 10 "github.com/juju/names" 11 12 "github.com/juju/juju/leadership" 13 ) 14 15 // claim is used to deliver leadership-claim requests to a manager's loop 16 // goroutine on behalf of ClaimLeadership. 17 type claim struct { 18 serviceName string 19 unitName string 20 duration time.Duration 21 response chan bool 22 abort <-chan struct{} 23 } 24 25 // validate returns an error if any fields are invalid or missing. 26 func (c claim) validate() error { 27 if !names.IsValidService(c.serviceName) { 28 return errors.Errorf("invalid service name %q", c.serviceName) 29 } 30 if !names.IsValidUnit(c.unitName) { 31 return errors.Errorf("invalid unit name %q", c.unitName) 32 } 33 if c.duration <= 0 { 34 return errors.Errorf("invalid duration %v", c.duration) 35 } 36 if c.response == nil { 37 return errors.New("missing response channel") 38 } 39 if c.abort == nil { 40 return errors.New("missing abort channel") 41 } 42 return nil 43 } 44 45 // invoke sends the claim on the supplied channel and waits for a response. 46 func (c claim) invoke(ch chan<- claim) error { 47 if err := c.validate(); err != nil { 48 return errors.Annotatef(err, "cannot claim leadership") 49 } 50 for { 51 select { 52 case <-c.abort: 53 return errStopped 54 case ch <- c: 55 ch = nil 56 case success := <-c.response: 57 if !success { 58 return leadership.ErrClaimDenied 59 } 60 return nil 61 } 62 } 63 } 64 65 // respond causes the supplied success value to be sent back to invoke. 66 func (c claim) respond(success bool) { 67 select { 68 case <-c.abort: 69 case c.response <- success: 70 } 71 }