-
Notifications
You must be signed in to change notification settings - Fork 6
/
rpc_impl.go
140 lines (112 loc) · 3.2 KB
/
rpc_impl.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
139
140
package gmaj
import (
"errors"
"github.com/r-medina/gmaj/gmajpb"
"golang.org/x/net/context"
)
var (
emptyRemote = &gmajpb.Node{}
mt = &gmajpb.MT{}
)
// GetPredecessor gets the predecessor on the node.
func (node *Node) GetPredecessor(context.Context, *gmajpb.MT) (*gmajpb.Node, error) {
node.predMtx.RLock()
pred := node.predecessor
node.predMtx.RUnlock()
if pred == nil {
return emptyRemote, nil
}
return pred, nil
}
// GetSuccessor gets the successor on the node..
func (node *Node) GetSuccessor(context.Context, *gmajpb.MT) (*gmajpb.Node, error) {
node.succMtx.RLock()
succ := node.successor
node.succMtx.RUnlock()
if succ == nil {
return emptyRemote, nil
}
return succ, nil
}
// SetPredecessor sets the predecessor on the node.
func (node *Node) SetPredecessor(
ctx context.Context, pred *gmajpb.Node,
) (*gmajpb.MT, error) {
node.predMtx.Lock()
node.predecessor = pred
node.predMtx.Unlock()
return mt, nil
}
// SetSuccessor sets the successor on the node.
func (node *Node) SetSuccessor(
ctx context.Context, succ *gmajpb.Node,
) (*gmajpb.MT, error) {
node.succMtx.Lock()
node.successor = succ
node.succMtx.Unlock()
return mt, nil
}
// Notify is called when remoteNode thinks it's our predecessor.
func (node *Node) Notify(
ctx context.Context, remoteNode *gmajpb.Node,
) (*gmajpb.MT, error) {
node.notify(remoteNode)
// If node.Predecessor is nil at this point, we were trying to notify
// ourselves. Otherwise, to succeed, we must check that the successor
// was correctly updated.
node.predMtx.Lock()
defer node.predMtx.Unlock()
if node.predecessor != nil && !idsEqual(node.predecessor.Id, remoteNode.Id) {
return nil, errors.New("gmaj: node is not predecesspr")
}
return mt, nil
}
// ClosestPrecedingFinger will find the closest preceding entry in the finger
// table based on the id.
func (node *Node) ClosestPrecedingFinger(
ctx context.Context, id *gmajpb.ID,
) (*gmajpb.Node, error) {
remoteNode := node.closestPrecedingFinger(id.Id)
if remoteNode == nil {
return nil, errors.New("gmaj: no closest preceding finger")
}
return remoteNode, nil
}
// FindSuccessor finds the successor, error if nil.
func (node *Node) FindSuccessor(
ctx context.Context, id *gmajpb.ID,
) (*gmajpb.Node, error) {
succ, err := node.findSuccessor(id.Id)
if err != nil {
return emptyRemote, err
}
if succ == nil {
return nil, errors.New("gmaj: cannot find successor")
}
return succ, nil
}
// GetKey returns the value of the key requested at the node.
func (node *Node) GetKey(ctx context.Context, key *gmajpb.Key) (*gmajpb.Val, error) {
val, err := node.getKey(key.Key)
if err != nil {
return nil, err
}
return &gmajpb.Val{Val: val}, nil
}
// PutKeyVal stores a key value pair on the node.
func (node *Node) PutKeyVal(ctx context.Context, kv *gmajpb.KeyVal) (*gmajpb.MT, error) {
if err := node.putKeyVal(kv); err != nil {
return nil, err
}
return mt, nil
}
// TransferKeys transfers the appropriate keys on this node
// to the remote node specified in the request.
func (node *Node) TransferKeys(
ctx context.Context, tmsg *gmajpb.TransferKeysReq,
) (*gmajpb.MT, error) {
if err := node.transferKeys(tmsg.FromId, tmsg.ToNode); err != nil {
return nil, err
}
return mt, nil
}