Skip to content

Commit 9733714

Browse files
committed
feat: add WithNodes function NodeID-to-StructMapping
1 parent a584ebd commit 9733714

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

config_opts.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,44 @@ type NodeListOption interface {
1111
newConfig(*Manager) (Configuration, error)
1212
}
1313

14+
// NodeAddress must be implemented by types that can be used as node addresses.
15+
type NodeAddress interface {
16+
Addr() string
17+
}
18+
19+
type structNodeMap[T NodeAddress] struct {
20+
nodes map[uint32]T
21+
}
22+
23+
func (structNodeMap[T]) isOption() {}
24+
25+
func (o structNodeMap[T]) newConfig(mgr *Manager) (nodes Configuration, err error) {
26+
if len(o.nodes) == 0 {
27+
return nil, fmt.Errorf("config: missing required node map")
28+
}
29+
nodes = make(Configuration, 0, len(o.nodes))
30+
for id, n := range o.nodes {
31+
node, found := mgr.Node(id)
32+
if !found {
33+
node, err = mgr.newNode(n.Addr(), id)
34+
if err != nil {
35+
return nil, err
36+
}
37+
}
38+
nodes = append(nodes, node)
39+
}
40+
// Sort nodes to ensure deterministic iteration.
41+
OrderedBy(ID).Sort(mgr.nodes)
42+
OrderedBy(ID).Sort(nodes)
43+
return nodes, nil
44+
}
45+
46+
// WithNodes returns a NodeListOption containing the provided
47+
// mapping from application-specific IDs to types implementing NodeAddress.
48+
func WithNodes[T NodeAddress](nodes map[uint32]T) NodeListOption {
49+
return &structNodeMap[T]{nodes: nodes}
50+
}
51+
1452
type nodeIDMap struct {
1553
idMap map[string]uint32
1654
}

config_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,47 @@ func TestNewConfigurationNodeMap(t *testing.T) {
101101
}
102102
}
103103

104+
type testNode struct {
105+
addr string
106+
}
107+
108+
func (n testNode) Addr() string {
109+
return n.addr
110+
}
111+
112+
func TestNewConfigurationWithNodes(t *testing.T) {
113+
mgr := gorums.NewManager(gorums.InsecureDialOptions(t))
114+
t.Cleanup(gorums.Closer(t, mgr))
115+
116+
nodes := map[uint32]testNode{
117+
1: {addr: "127.0.0.1:9080"},
118+
2: {addr: "127.0.0.1:9081"},
119+
3: {addr: "127.0.0.1:9082"},
120+
4: {addr: "127.0.0.1:9083"},
121+
}
122+
123+
cfg, err := gorums.NewConfiguration(mgr, gorums.WithNodes(nodes))
124+
if err != nil {
125+
t.Fatal(err)
126+
}
127+
if cfg.Size() != len(nodes) {
128+
t.Errorf("cfg.Size() = %d, expected %d", cfg.Size(), len(nodes))
129+
}
130+
for _, node := range cfg.Nodes() {
131+
if nodes[node.ID()].addr != node.Address() {
132+
t.Errorf("cfg.Nodes()[%d] = %s, expected %s", node.ID(), node.Address(), nodes[node.ID()].addr)
133+
}
134+
}
135+
if mgr.Size() != len(nodes) {
136+
t.Errorf("mgr.Size() = %d, expected %d", mgr.Size(), len(nodes))
137+
}
138+
for _, node := range mgr.Nodes() {
139+
if nodes[node.ID()].addr != node.Address() {
140+
t.Errorf("mgr.Nodes()[%d] = %s, expected %s", node.ID(), node.Address(), nodes[node.ID()].addr)
141+
}
142+
}
143+
}
144+
104145
func TestNewConfigurationNodeIDs(t *testing.T) {
105146
mgr := gorums.NewManager(gorums.InsecureDialOptions(t))
106147
t.Cleanup(gorums.Closer(t, mgr))

0 commit comments

Comments
 (0)