forked from st3v/go-plugins
/
consul.go
138 lines (116 loc) · 2.93 KB
/
consul.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
132
133
134
135
136
137
138
package main
import (
"fmt"
"time"
"github.com/micro/go-micro/registry"
"github.com/micro/go-os/sync"
"github.com/micro/go-plugins/sync/consul"
)
func leaderStatus(i int, s sync.Leader, msg string) {
status, err := s.Status()
if err != nil {
fmt.Printf("[leader:%d] error getting leader status %v", i, err)
return
}
fmt.Printf("[leader:%d] [status:%v] %s\n", i, status, msg)
}
func acquire(i int, s sync.Sync) {
l, err := s.Lock("alock")
if err != nil {
fmt.Printf("[lock:%d] err acquiring lock interface %v\n", i, err)
return
}
fmt.Printf("[lock:%d] attempting to acquire lock\n", i)
if err := l.Acquire(); err != nil {
fmt.Printf("[lock:%d] err acquiring lock %v\n", i, err)
return
}
fmt.Printf("[lock:%d] acquired lock!\n", i)
time.Sleep(time.Second)
fmt.Printf("[lock:%d] unlocking now\n", i)
if err := l.Release(); err != nil {
fmt.Printf("[lock:%d] err releasing lock %v\n", i, err)
}
fmt.Printf("[lock:%d] unlocked\n", i)
}
func leader(i int, s sync.Sync) {
// Get a leader interface
l, err := s.Leader("king")
if err != nil {
fmt.Printf("[leader:%d] err acquiring leader interface %v\n", i, err)
return
}
leader, err := l.Leader()
if err != nil {
fmt.Printf("[leader:%d] err getting current leader %v\n", i, err)
leaderStatus(i, l, "attempting to elect self")
} else {
leaderStatus(i, l, fmt.Sprintf("attempting to elect self. current leader %v", leader))
}
// Attempt to elect self
throne, err := l.Elect()
if err != nil {
fmt.Printf("[leader:%d] err electing self %v\n", i, err)
return
}
leaderStatus(i, l, "elected as leader")
j := 0
revoked, err := throne.Revoked()
if err != nil {
fmt.Printf("[leader:%d] throne already revoked, gnarly %v\n", i, err)
}
loop:
for {
select {
// Check if we've been revoked
case <-revoked:
leaderStatus(i, l, "leadership revoked")
return
default:
leaderStatus(i, l, "I'm leading son")
time.Sleep(time.Second)
}
if j >= 3 {
break loop
}
j++
}
leader, err = l.Leader()
if err != nil {
fmt.Printf("[leader:%d] err getting current leader %v\n", i, err)
} else {
leaderStatus(i, l, fmt.Sprintf("current leader %v", leader))
}
leaderStatus(i, l, "resigning now")
// Resign leadership status
if err := throne.Resign(); err != nil {
leaderStatus(i, l, fmt.Sprintf("err resigning %v", err))
}
leaderStatus(i, l, "resigned")
}
func main() {
// Acquire locks
for i := 0; i < 2; i++ {
go acquire(i, consul.NewSync())
}
acquire(2, consul.NewSync())
// Acquire leadership
for i := 0; i < 2; i++ {
go leader(i, consul.NewSync(
sync.Service(®istry.Service{
Name: "foo",
Version: "latest",
Nodes: []*registry.Node{®istry.Node{Id: fmt.Sprintf("foo-%d", i)}},
}),
))
}
leader(2, consul.NewSync(
sync.Service(®istry.Service{
Name: "foo",
Version: "latest",
Nodes: []*registry.Node{®istry.Node{Id: "foo-2"}},
}),
))
// Sleep just for fun
time.Sleep(time.Second * 5)
}