1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
package nodes
import (
"context"
"sync"
"time"
"gitlab.com/gitlab-org/gitaly/v14/internal/praefect/metrics"
)
// newDisabledElector returns a stub that always returns the same shard where the
// primary is the first node from the passed in list.
func newDisabledElector(virtualStorage string, ns []*nodeStatus) *disabledElector {
secondaries := make([]Node, len(ns)-1)
for i, node := range ns[1:] {
secondaries[i] = node
}
return &disabledElector{
virtualStorage: virtualStorage,
shard: Shard{Primary: ns[0], Secondaries: secondaries},
}
}
type disabledElector struct {
shard Shard
virtualStorage string
}
func (de *disabledElector) start(bootstrap, _ time.Duration) {
timer := time.NewTimer(bootstrap)
defer timer.Stop()
for i := 0; i < healthcheckThreshold; i++ {
<-timer.C
ctx := context.TODO()
_ = de.checkNodes(ctx)
timer.Reset(bootstrap)
}
de.updateMetrics()
}
func (de *disabledElector) updateMetrics() {
metrics.PrimaryGauge.WithLabelValues(de.virtualStorage, de.shard.Primary.GetStorage()).Set(1)
for _, n := range de.shard.Secondaries {
metrics.PrimaryGauge.WithLabelValues(de.virtualStorage, n.GetStorage()).Set(0)
}
}
func (de *disabledElector) checkNodes(ctx context.Context) error {
var wg sync.WaitGroup
for _, n := range append(de.shard.Secondaries, de.shard.Primary) {
wg.Add(1)
go func(n Node) {
defer wg.Done()
_, _ = n.CheckHealth(ctx)
}(n)
}
wg.Wait()
return nil
}
func (de *disabledElector) GetShard(ctx context.Context) (Shard, error) {
if !de.shard.Primary.IsHealthy() {
return Shard{}, ErrPrimaryNotHealthy
}
return de.shard, nil
}
|