mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
discovery: store size inside /[cluster]/config
This commit is contained in:
parent
00d1daaf1e
commit
6081311db5
@ -14,7 +14,7 @@ import (
|
||||
|
||||
var (
|
||||
ErrInvalidURL = errors.New("discovery: invalid URL")
|
||||
ErrBadCluster = errors.New("discovery: bad key/value inside cluster")
|
||||
ErrBadSizeKey = errors.New("discovery: size key is bad")
|
||||
ErrSizeNotFound = errors.New("discovery: size key not found")
|
||||
ErrTokenNotFound = errors.New("discovery: token not found")
|
||||
ErrDuplicateID = errors.New("discovery: found duplicate id")
|
||||
@ -69,26 +69,35 @@ func (d *discovery) createSelf() error {
|
||||
}
|
||||
|
||||
func (d *discovery) checkCluster() (client.Nodes, int, error) {
|
||||
resp, err := d.c.Get(d.cluster)
|
||||
configKey := path.Join("/", d.cluster, "config")
|
||||
// find cluster size
|
||||
resp, err := d.c.Get(path.Join(configKey, "size"))
|
||||
if err != nil {
|
||||
if err == client.ErrKeyNoExist {
|
||||
return nil, 0, ErrSizeNotFound
|
||||
}
|
||||
return nil, 0, err
|
||||
}
|
||||
size, err := strconv.Atoi(resp.Node.Value)
|
||||
if err != nil {
|
||||
return nil, 0, ErrBadSizeKey
|
||||
}
|
||||
|
||||
resp, err = d.c.Get(d.cluster)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
nodes := resp.Node.Nodes
|
||||
nodes := make(client.Nodes, 0)
|
||||
// append non-config keys to nodes
|
||||
for _, n := range resp.Node.Nodes {
|
||||
if !strings.HasPrefix(n.Key, configKey) {
|
||||
nodes = append(nodes, n)
|
||||
}
|
||||
}
|
||||
|
||||
snodes := SortableNodes{nodes}
|
||||
sort.Sort(snodes)
|
||||
|
||||
// find cluster size
|
||||
if nodes[0].Key != path.Join("/", d.cluster, "size") {
|
||||
return nil, 0, ErrSizeNotFound
|
||||
}
|
||||
size, err := strconv.Atoi(nodes[0].Value)
|
||||
if err != nil {
|
||||
return nil, 0, ErrBadCluster
|
||||
}
|
||||
|
||||
// remove size key from nodes
|
||||
nodes = nodes[1:]
|
||||
|
||||
// find self position
|
||||
for i := range nodes {
|
||||
if nodes[i].Key == d.selfKey() {
|
||||
|
@ -25,7 +25,7 @@ func TestCheckCluster(t *testing.T) {
|
||||
{
|
||||
// self is in the size range
|
||||
client.Nodes{
|
||||
{Key: "/1000/size", Value: "3", CreatedIndex: 1},
|
||||
{Key: "/1000/config/size", Value: "3", CreatedIndex: 1},
|
||||
{Key: self, CreatedIndex: 2},
|
||||
{Key: "/1000/2", CreatedIndex: 3},
|
||||
{Key: "/1000/3", CreatedIndex: 4},
|
||||
@ -37,7 +37,7 @@ func TestCheckCluster(t *testing.T) {
|
||||
{
|
||||
// self is in the size range
|
||||
client.Nodes{
|
||||
{Key: "/1000/size", Value: "3", CreatedIndex: 1},
|
||||
{Key: "/1000/config/size", Value: "3", CreatedIndex: 1},
|
||||
{Key: "/1000/2", CreatedIndex: 2},
|
||||
{Key: "/1000/3", CreatedIndex: 3},
|
||||
{Key: self, CreatedIndex: 4},
|
||||
@ -49,7 +49,7 @@ func TestCheckCluster(t *testing.T) {
|
||||
{
|
||||
// self is out of the size range
|
||||
client.Nodes{
|
||||
{Key: "/1000/size", Value: "3", CreatedIndex: 1},
|
||||
{Key: "/1000/config/size", Value: "3", CreatedIndex: 1},
|
||||
{Key: "/1000/2", CreatedIndex: 2},
|
||||
{Key: "/1000/3", CreatedIndex: 3},
|
||||
{Key: "/1000/4", CreatedIndex: 4},
|
||||
@ -61,7 +61,7 @@ func TestCheckCluster(t *testing.T) {
|
||||
{
|
||||
// self is not in the cluster
|
||||
client.Nodes{
|
||||
{Key: "/1000/size", Value: "3", CreatedIndex: 1},
|
||||
{Key: "/1000/config/size", Value: "3", CreatedIndex: 1},
|
||||
{Key: "/1000/2", CreatedIndex: 2},
|
||||
{Key: "/1000/3", CreatedIndex: 3},
|
||||
},
|
||||
@ -70,7 +70,7 @@ func TestCheckCluster(t *testing.T) {
|
||||
},
|
||||
{
|
||||
client.Nodes{
|
||||
{Key: "/1000/size", Value: "3", CreatedIndex: 1},
|
||||
{Key: "/1000/config/size", Value: "3", CreatedIndex: 1},
|
||||
{Key: "/1000/2", CreatedIndex: 2},
|
||||
{Key: "/1000/3", CreatedIndex: 3},
|
||||
{Key: "/1000/4", CreatedIndex: 4},
|
||||
@ -81,34 +81,33 @@ func TestCheckCluster(t *testing.T) {
|
||||
{
|
||||
// bad size key
|
||||
client.Nodes{
|
||||
{Key: "/1000/size", Value: "bad", CreatedIndex: 1},
|
||||
{Key: "/1000/config/size", Value: "bad", CreatedIndex: 1},
|
||||
},
|
||||
ErrBadCluster,
|
||||
ErrBadSizeKey,
|
||||
0,
|
||||
},
|
||||
{
|
||||
// no size key
|
||||
client.Nodes{
|
||||
{Key: self, CreatedIndex: 1},
|
||||
},
|
||||
client.Nodes{},
|
||||
ErrSizeNotFound,
|
||||
0,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
resp := &client.Response{
|
||||
Node: &client.Node{
|
||||
Key: cluster,
|
||||
Nodes: tt.nodes,
|
||||
},
|
||||
rs := make([]*client.Response, 0)
|
||||
if len(tt.nodes) > 0 {
|
||||
rs = append(rs, &client.Response{Node: tt.nodes[0]})
|
||||
rs = append(rs, &client.Response{
|
||||
Node: &client.Node{
|
||||
Key: cluster,
|
||||
Nodes: tt.nodes,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
c := &clientWithResp{
|
||||
rs: []*client.Response{resp},
|
||||
}
|
||||
|
||||
c := &clientWithResp{rs: rs}
|
||||
d := discovery{cluster: cluster, id: 1, c: c}
|
||||
|
||||
ns, size, err := d.checkCluster()
|
||||
if err != tt.werr {
|
||||
t.Errorf("#%d: err = %v, want %v", i, err, tt.werr)
|
||||
@ -277,7 +276,7 @@ func (c *clientWithResp) Create(key string, value string, ttl time.Duration) (*c
|
||||
|
||||
func (c *clientWithResp) Get(key string) (*client.Response, error) {
|
||||
if len(c.rs) == 0 {
|
||||
return &client.Response{}, nil
|
||||
return &client.Response{}, client.ErrKeyNoExist
|
||||
}
|
||||
r := c.rs[0]
|
||||
c.rs = c.rs[1:]
|
||||
|
Loading…
x
Reference in New Issue
Block a user