@@ -31,7 +31,15 @@ import (
3131 "github.com/arangodb/kube-arangodb/pkg/util/errors"
3232)
3333
34- type health map [string ]uint64
34+ type health struct {
35+ leaderID string
36+
37+ commitIndexes map [string ]uint64
38+ }
39+
40+ func (h health ) LeaderID () string {
41+ return h .leaderID
42+ }
3543
3644// IsHealthy returns true if all agencies have the same commit index.
3745// Returns false when:
@@ -42,7 +50,7 @@ func (h health) IsHealthy() bool {
4250 var globalCommitIndex uint64
4351 first := true
4452
45- for _ , commitIndex := range h {
53+ for _ , commitIndex := range h . commitIndexes {
4654 if first {
4755 globalCommitIndex = commitIndex
4856 first = false
@@ -58,14 +66,15 @@ func (h health) IsHealthy() bool {
5866type Health interface {
5967 // IsHealthy return true when environment is considered as healthy.
6068 IsHealthy () bool
69+
70+ // LeaderID returns a leader ID or empty string if a leader is not known.
71+ LeaderID () string
6172}
6273
6374type Cache interface {
6475 Reload (ctx context.Context , clients []agency.Agency ) (uint64 , error )
6576 Data () (State , bool )
6677 CommitIndex () uint64
67- // GetLeaderID returns a leader ID.
68- GetLeaderID () string
6978 // Health returns true when healthy object is available.
7079 Health () (Health , bool )
7180}
@@ -93,11 +102,6 @@ func (c cacheSingle) CommitIndex() uint64 {
93102 return 0
94103}
95104
96- // GetLeaderID returns always empty string for a single cache.
97- func (c cacheSingle ) GetLeaderID () string {
98- return ""
99- }
100-
101105// Health returns always false for single cache.
102106func (c cacheSingle ) Health () (Health , bool ) {
103107 return nil , false
@@ -121,8 +125,6 @@ type cache struct {
121125 data State
122126
123127 health Health
124-
125- leaderID string
126128}
127129
128130func (c * cache ) CommitIndex () uint64 {
@@ -139,14 +141,6 @@ func (c *cache) Data() (State, bool) {
139141 return c .data , c .valid
140142}
141143
142- // GetLeaderID returns a leader ID or empty string if a leader is not known.
143- func (c * cache ) GetLeaderID () string {
144- c .lock .RLock ()
145- defer c .lock .RUnlock ()
146-
147- return c .leaderID
148- }
149-
150144// Health returns always false for single cache.
151145func (c * cache ) Health () (Health , bool ) {
152146 c .lock .RLock ()
@@ -167,7 +161,6 @@ func (c *cache) Reload(ctx context.Context, clients []agency.Agency) (uint64, er
167161 if err != nil {
168162 // Invalidate a leader ID and agency state.
169163 // In the next iteration leaderID will be sat because `valid` will be false.
170- c .leaderID = ""
171164 c .valid = false
172165
173166 return 0 , err
@@ -180,7 +173,6 @@ func (c *cache) Reload(ctx context.Context, clients []agency.Agency) (uint64, er
180173 }
181174
182175 // A leader should be known even if an agency state is invalid.
183- c .leaderID = leaderConfig .LeaderId
184176 if data , err := loadState (ctx , leaderCli ); err != nil {
185177 c .valid = false
186178 return leaderConfig .CommitIndex , err
@@ -194,7 +186,7 @@ func (c *cache) Reload(ctx context.Context, clients []agency.Agency) (uint64, er
194186
195187// getLeader returns config and client to a leader agency, and health to check if agencies are on the same page.
196188// If there is no quorum for the leader then error is returned.
197- func getLeader (ctx context.Context , clients []agency.Agency ) (agency.Agency , * agencyConfig , Health , error ) {
189+ func getLeader (ctx context.Context , clients []agency.Agency ) (agency.Agency , * Config , Health , error ) {
198190 var mutex sync.Mutex
199191 var anyError error
200192 var wg sync.WaitGroup
@@ -203,10 +195,12 @@ func getLeader(ctx context.Context, clients []agency.Agency) (agency.Agency, *ag
203195 if cliLen == 0 {
204196 return nil , nil , nil , errors .New ("empty list of agencies' clients" )
205197 }
206- configs := make ([]* agencyConfig , cliLen )
207- leaders := make (map [string ]int )
198+ configs := make ([]* Config , cliLen )
199+ leaders := make (map [string ]int , cliLen )
208200
209- h := make (health )
201+ var h health
202+
203+ h .commitIndexes = make (map [string ]uint64 , cliLen )
210204 // Fetch all configs from agencies.
211205 wg .Add (cliLen )
212206 for i , cli := range clients {
@@ -215,7 +209,7 @@ func getLeader(ctx context.Context, clients []agency.Agency) (agency.Agency, *ag
215209
216210 ctxLocal , cancel := context .WithTimeout (ctx , time .Second )
217211 defer cancel ()
218- config , err := getAgencyConfig (ctxLocal , cliLocal )
212+ config , err := GetAgencyConfig (ctxLocal , cliLocal )
219213
220214 mutex .Lock ()
221215 defer mutex .Unlock ()
@@ -232,7 +226,7 @@ func getLeader(ctx context.Context, clients []agency.Agency) (agency.Agency, *ag
232226 configs [iLocal ] = config
233227 // Count leaders.
234228 leaders [config .LeaderId ]++
235- h [config .Configuration .ID ] = config .CommitIndex
229+ h . commitIndexes [config .Configuration .ID ] = config .CommitIndex
236230 }(i , cli )
237231 }
238232 wg .Wait ()
@@ -255,6 +249,8 @@ func getLeader(ctx context.Context, clients []agency.Agency) (agency.Agency, *ag
255249 }
256250 }
257251
252+ h .leaderID = leaderID
253+
258254 // Check if a leader has quorum from all possible agencies.
259255 if maxVotes <= cliLen / 2 {
260256 message := fmt .Sprintf ("no quorum for leader %s, votes %d of %d" , leaderID , maxVotes , cliLen )
0 commit comments