github.com/juju/juju@v0.0.0-20240327075706-a90865de2538/core/leadership/interface.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 "fmt" 8 "time" 9 10 "github.com/juju/errors" 11 "github.com/juju/worker/v3" 12 ) 13 14 // TODO (manadart 2018-10-05) Add interfaces to the end of this line, 15 // separated by commas, as they become required for mocking in tests. 16 //go:generate go run go.uber.org/mock/mockgen -package mocks -destination mocks/leadership_mock.go github.com/juju/juju/core/leadership Pinner 17 18 const ( 19 // ErrClaimDenied is the error which will be returned when a 20 // leadership claim has been denied. 21 ErrClaimDenied = errors.ConstError("leadership claim denied") 22 23 // ErrClaimNotHeld is the error which will be returned when a 24 // leadership lease is not held. 25 ErrClaimNotHeld = errors.ConstError("leadership lease not held") 26 27 // ErrBlockCancelled is returned from BlockUntilLeadershipReleased 28 // if the client cancels the request by closing the cancel channel. 29 ErrBlockCancelled = errors.ConstError("waiting for leadership cancelled by client") 30 ) 31 32 // NewNotLeaderError returns an error indicating that this unit is not 33 // the leader of that application. 34 func NewNotLeaderError(unit, application string) error { 35 return ¬LeaderError{unit: unit, application: application} 36 } 37 38 type notLeaderError struct { 39 unit string 40 application string 41 } 42 43 // Error is part of error. 44 func (e notLeaderError) Error() string { 45 return fmt.Sprintf("%q is not leader of %q", e.unit, e.application) 46 } 47 48 // IsNotLeaderError returns whether this error represents a token 49 // check that failed because the unit in question wasn't the leader. 50 func IsNotLeaderError(err error) bool { 51 if err == nil { 52 return false 53 } 54 _, ok := errors.Cause(err).(*notLeaderError) 55 return ok 56 } 57 58 // Claimer exposes leadership acquisition capabilities. 59 type Claimer interface { 60 61 // ClaimLeadership claims leadership of the named application on behalf of the 62 // named unit. If no error is returned, leadership will be guaranteed for 63 // at least the supplied duration from the point when the call was made. 64 ClaimLeadership(applicationId, unitId string, duration time.Duration) error 65 66 // BlockUntilLeadershipReleased blocks until the named application is known 67 // to have no leader, in which case it returns no error; or until the 68 // manager is stopped, in which case it will fail. 69 BlockUntilLeadershipReleased(applicationId string, cancel <-chan struct{}) (err error) 70 } 71 72 // Revoker exposes leadership revocation capabilities. 73 type Revoker interface { 74 // RevokeLeadership revokes leadership of the named application 75 // on behalf of the named unit. 76 RevokeLeadership(applicationId, unitId string) error 77 } 78 79 // Pinner describes methods used to manage suspension of application leadership 80 // expiry. All methods should be idempotent. 81 type Pinner interface { 82 83 // PinLeadership ensures that the leadership of the input application will 84 // not expire. The input entity records the party responsible for the 85 // pinning operation. 86 PinLeadership(applicationId string, entity string) error 87 88 // UnpinLeadership reverses a PinLeadership operation for the same 89 // application and entity. Normal expiry behaviour is restored when no 90 // entities remain with pins for the application. 91 UnpinLeadership(applicationId string, entity string) error 92 93 // PinnedLeadership returns a map keyed on pinned application names, 94 // with entities that require the application's pinned behaviour. 95 PinnedLeadership() (map[string][]string, error) 96 } 97 98 // Token represents a unit's leadership of its application. 99 type Token interface { 100 // Check returns an error if the condition it embodies no longer holds. 101 Check() error 102 } 103 104 // Checker exposes leadership testing capabilities. 105 type Checker interface { 106 107 // LeadershipCheck returns a Token representing the supplied unit's 108 // application leadership. The existence of the token does not imply 109 // its accuracy; you need to Check() it. 110 // 111 // This method returns a token that accepts a *[]txn.Op, into which 112 // it will (on success) copy mgo/txn operations that can be used to 113 // verify the unit's continued leadership as part of another txn. 114 LeadershipCheck(applicationId, unitId string) Token 115 } 116 117 // Ticket is used to communicate leadership status to Tracker clients. 118 type Ticket interface { 119 120 // Wait returns true if its Tracker is prepared to guarantee leadership 121 // for some period from the ticket request. The guaranteed duration depends 122 // upon the Tracker. 123 Wait() bool 124 125 // Ready returns a channel that will be closed when a result is available 126 // to Wait(), and is helpful for clients that want to select rather than 127 // block on long-waiting tickets. 128 Ready() <-chan struct{} 129 } 130 131 // Tracker allows clients to discover current leadership status by attempting to 132 // claim it for themselves. 133 type Tracker interface { 134 135 // ApplicationName returns the name of the application for which leadership claims 136 // are made. 137 ApplicationName() string 138 139 // ClaimDuration returns the duration for which a Ticket's true Wait result 140 // is guaranteed valid. 141 ClaimDuration() time.Duration 142 143 // ClaimLeader will return a Ticket which, when Wait()ed for, will return 144 // true if leadership is guaranteed for at least the tracker's duration from 145 // the time the ticket was issued. Leadership claims should be resolved 146 // relatively quickly. 147 ClaimLeader() Ticket 148 149 // WaitLeader will return a Ticket which, when Wait()ed for, will block 150 // until the tracker attains leadership. 151 WaitLeader() Ticket 152 153 // WaitMinion will return a Ticket which, when Wait()ed for, will block 154 // until the tracker's future leadership can no longer be guaranteed. 155 WaitMinion() Ticket 156 } 157 158 // TrackerWorker represents a leadership tracker worker. 159 type TrackerWorker interface { 160 worker.Worker 161 Tracker 162 } 163 164 // Reader describes the capability to read the current state of leadership. 165 type Reader interface { 166 167 // Leaders returns all application leaders in the current model. 168 // TODO (manadart 2019-02-27): The return in this signature includes error 169 // in order to support state.ApplicationLeaders for legacy leases. 170 // When legacy leases are removed, so can the error return. 171 Leaders() (map[string]string, error) 172 }