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  }