/
user_client.go
125 lines (106 loc) · 2.99 KB
/
user_client.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
package reg
// xlReg_go/user_client.go
import (
"crypto/rsa"
"fmt"
xcl "github.com/jddixon/xlCluster_go"
xi "github.com/jddixon/xlNodeID_go"
xn "github.com/jddixon/xlNode_go"
xt "github.com/jddixon/xlTransport_go"
)
var _ = fmt.Print
// The UserMember is created to enable the caller to join a cluster
// and learn information about the cluster's other members. Once the
// client has learned that information, it is done.
// As implemented so far, this is an ephemeral client, meaning that it
// neither saves nor restores its Node; keys and such are generated for
// each instance.
// For practical use, it is essential that the UserMember create its
// Node when NewUserMember() is first called, but then save its
// configuration. This is conventionally written to LFS/.xlattice/config.
// On subsequent the client reads its configuration file rather than
// regenerating keys, etc.
type UserMember struct {
// members []MemberInfo // XXX Nowhere used
MemberMaker
}
func NewUserMember(
name, lfs string, ckPriv, skPriv *rsa.PrivateKey,
serverName string, serverID *xi.NodeID, serverEnd xt.EndPointI,
serverCK, serverSK *rsa.PublicKey,
clusterName string, clusterAttrs uint64, clusterID *xi.NodeID,
size, epCount uint32, e []xt.EndPointI) (ac *UserMember, err error) {
var attrs uint64
nodeID, err := xi.New(nil)
if err == nil {
if lfs == "" {
attrs |= xcl.ATTR_EPHEMERAL
}
node, err := xn.New(name, nodeID, lfs, ckPriv, skPriv, nil, nil, nil)
if err == nil {
mn, err := NewMemberMaker(node,
attrs,
serverName, serverID, serverEnd,
serverCK, serverSK, // *rsa.PublicKey,
clusterName, clusterAttrs, clusterID, size,
epCount, e)
if err == nil {
// Start() fills in clusterID
ac = &UserMember{
MemberMaker: *mn,
}
}
}
}
return
}
// Start the member running in separate goroutine, so that this function
// is non-blocking.
func (uc *UserMember) Start() {
var err error
mn := &uc.MemberMaker
err = mn.OpenAcc() // runs the node, opening acceptors
if err == nil {
go func() {
var (
cnx *xt.TcpConnection
version1 uint32
version2 uint32
)
cnx, version2, err = mn.SessionSetup(version1)
if cnx != nil {
defer cnx.Close()
}
_ = version2 // not yet used
if err == nil {
err = mn.MemberAndOK()
}
// XXX MODIFY TO USE CLUSTER_ID PASSED TO UserMember
// 2013-10-12 this is a join by cluster name
if err == nil {
err = mn.JoinAndReply()
}
if err == nil {
err = mn.GetAndMembers()
}
// DEBUG ====================================================
var nilMembers []int
for i := 0; i < len(uc.Members); i++ {
if uc.Members[i] == nil {
nilMembers = append(nilMembers, i)
}
}
if len(nilMembers) > 0 {
fmt.Printf("UserMember.Start() after Get finds nil members: %v\n",
nilMembers)
}
// END ======================================================
if err == nil {
err = mn.ByeAndAck()
}
mn.DoneCh <- err
}()
} else {
mn.DoneCh <- err
}
}