-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathServiceCluster.go
90 lines (75 loc) · 2.17 KB
/
ServiceCluster.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
package main
import (
"errors"
"github.com/golang/glog"
"sync"
)
type ServiceCluster struct {
instances []*Service
lastIndex int
lock sync.RWMutex
}
func (cl *ServiceCluster) Next() (*Service, error) {
if cl == nil {
return nil, StatusError{}
}
cl.lock.RLock()
defer cl.lock.RUnlock()
if len(cl.instances) == 0 {
return nil, errors.New("no alive instance found")
}
var instance *Service
for tries := 0; tries < len(cl.instances); tries++ {
index := (cl.lastIndex + 1) % len(cl.instances)
cl.lastIndex = index
instance = cl.instances[index]
glog.V(5).Infof("Checking instance %d status : %s", index, instance.status.compute())
if instance.status.compute() == STARTED_STATUS && instance.location.isFullyDefined() {
return instance, nil
}
}
lastStatus := instance.status
if lastStatus == nil && !instance.location.isFullyDefined() {
glog.Infof("No status and no location for %s", instance.name)
return nil, StatusError{ERROR_STATUS, lastStatus}
}
glog.V(5).Infof("No instance started for %s", instance.name)
glog.V(5).Infof("Last status :")
glog.V(5).Infof(" current : %s", lastStatus.current)
glog.V(5).Infof(" expected : %s", lastStatus.expected)
glog.V(5).Infof(" alive : %s", lastStatus.alive)
return nil, StatusError{instance.status.compute(), lastStatus}
}
func (cl *ServiceCluster) Remove(instanceIndex string) {
match := -1
for k, v := range cl.instances {
if v.index == instanceIndex {
match = k
}
}
cl.instances = append(cl.instances[:match], cl.instances[match+1:]...)
cl.Dump("remove")
}
// Get an service by its key (index). Returns nil if not found.
func (cl *ServiceCluster) Get(instanceIndex string) *Service {
for i, v := range cl.instances {
if v.index == instanceIndex {
return cl.instances[i]
}
}
return nil
}
func (cl *ServiceCluster) Add(service *Service) {
for index, v := range cl.instances {
if v.index == service.index {
cl.instances[index] = service
return
}
}
cl.instances = append(cl.instances, service)
}
func (cl *ServiceCluster) Dump(action string) {
for _, v := range cl.instances {
glog.Infof("Dump after %s %s -> %s:%d", action, v.index, v.location.Host, v.location.Port)
}
}