/
cluster.go
131 lines (102 loc) · 2.1 KB
/
cluster.go
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package failover
import (
"fmt"
"sync"
"time"
)
type Cluster interface {
Close()
AddMasters(addrs []string, timeout time.Duration) error
DelMasters(addrs []string, timeout time.Duration) error
SetMasters(addrs []string, timeout time.Duration) error
Barrier(timeout time.Duration) error
IsLeader() bool
LeaderCh() <-chan bool
}
// save monitored master addr
type masterFSM struct {
sync.Mutex
masters map[string]struct{}
}
func newMasterFSM() *masterFSM {
fsm := new(masterFSM)
fsm.masters = make(map[string]struct{})
return fsm
}
func (fsm *masterFSM) AddMasters(addrs []string) {
fsm.Lock()
defer fsm.Unlock()
for _, addr := range addrs {
if len(addr) == 0 {
continue
}
fsm.masters[addr] = struct{}{}
}
}
func (fsm *masterFSM) DelMasters(addrs []string) {
fsm.Lock()
defer fsm.Unlock()
for _, addr := range addrs {
if len(addr) == 0 {
continue
}
delete(fsm.masters, addr)
}
}
func (fsm *masterFSM) SetMasters(addrs []string) {
m := make(map[string]struct{}, len(addrs))
for _, addr := range addrs {
if len(addr) == 0 {
continue
}
m[addr] = struct{}{}
}
fsm.Lock()
defer fsm.Unlock()
fsm.masters = m
fmt.Printf("cluster.go SetMasters fsm.masters: %s\n", fsm.masters)
}
func (fsm *masterFSM) GetMasters() []string {
fsm.Lock()
defer fsm.Unlock()
m := make([]string, 0, len(fsm.masters))
for master := range fsm.masters {
m = append(m, master)
}
return m
}
func (fsm *masterFSM) IsMaster(addr string) bool {
fsm.Lock()
defer fsm.Unlock()
_, ok := fsm.masters[addr]
return ok
}
func (fsm *masterFSM) Copy() *masterFSM {
fsm.Lock()
defer fsm.Unlock()
o := new(masterFSM)
o.masters = make(map[string]struct{}, len(fsm.masters))
for master := range fsm.masters {
o.masters[master] = struct{}{}
}
return o
}
const (
addCmd = "add"
delCmd = "del"
setCmd = "set"
)
type action struct {
Cmd string `json:"cmd"`
Masters []string `json:"masters"`
}
func (fsm *masterFSM) handleAction(a *action) {
switch a.Cmd {
case addCmd:
fsm.AddMasters(a.Masters)
case delCmd:
fsm.DelMasters(a.Masters)
case setCmd:
fsm.SetMasters(a.Masters)
}
}