github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/leadership/leadership.go (about)

     1  // Copyright 2014 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  
    11  	"github.com/juju/juju/lease"
    12  )
    13  
    14  const (
    15  	leadershipDuration        = 30 * time.Second
    16  	leadershipNamespaceSuffix = "-leadership"
    17  )
    18  
    19  // NewLeadershipManager returns a new Manager.
    20  func NewLeadershipManager(leaseMgr LeadershipLeaseManager) *Manager {
    21  	return &Manager{
    22  		leaseMgr: leaseMgr,
    23  	}
    24  }
    25  
    26  // Manager represents the business logic for leadership management.
    27  type Manager struct {
    28  	leaseMgr LeadershipLeaseManager
    29  }
    30  
    31  // Leader returns whether or not the given unit id is currently the
    32  // leader for the given service ID.
    33  func (m *Manager) Leader(sid, uid string) bool {
    34  	tok := m.leaseMgr.RetrieveLease(leadershipNamespace(sid))
    35  	return tok.Id == uid
    36  }
    37  
    38  // ClaimLeadership implements the LeadershipManager interface.
    39  func (m *Manager) ClaimLeadership(sid, uid string) (time.Duration, error) {
    40  
    41  	_, err := m.leaseMgr.ClaimLease(leadershipNamespace(sid), uid, leadershipDuration)
    42  	if err != nil {
    43  		if errors.Cause(err) == lease.LeaseClaimDeniedErr {
    44  			err = errors.Wrap(err, LeadershipClaimDeniedErr)
    45  		} else {
    46  			err = errors.Annotate(err, "unable to make a leadership claim.")
    47  		}
    48  	}
    49  
    50  	return leadershipDuration, err
    51  }
    52  
    53  // ReleaseLeadership implements the LeadershipManager interface.
    54  func (m *Manager) ReleaseLeadership(sid, uid string) error {
    55  	return m.leaseMgr.ReleaseLease(leadershipNamespace(sid), uid)
    56  }
    57  
    58  // BlockUntilLeadershipReleased implements the LeadershipManager interface.
    59  func (m *Manager) BlockUntilLeadershipReleased(serviceId string) error {
    60  	notifier := m.leaseMgr.LeaseReleasedNotifier(leadershipNamespace(serviceId))
    61  	<-notifier
    62  	return nil
    63  }
    64  
    65  func leadershipNamespace(serviceId string) string {
    66  	return serviceId + leadershipNamespaceSuffix
    67  }