From 216ba7a41ec42ef3407ab5a59555fb4ce2c0757d Mon Sep 17 00:00:00 2001 From: Travis Turner Date: Thu, 1 Feb 2018 12:59:42 -0600 Subject: [PATCH 1/3] Use NodeID instead of URI for node identification --- broadcast.go | 13 +- client_test.go | 22 +- cluster.go | 517 +++++++++++++++------------ cluster_internal_test.go | 122 ++++--- cluster_test.go | 151 ++++---- ctl/backup_test.go | 4 +- ctl/export_test.go | 6 +- ctl/import_test.go | 12 +- ctl/restore_test.go | 4 +- event.go | 2 +- executor.go | 18 +- fragment.go | 6 +- gossip/gossip.go | 41 ++- handler.go | 84 +++-- handler_test.go | 6 +- holder.go | 54 +-- holder_test.go | 8 +- internal/private.pb.go | 747 ++++++++++++++++++++++++--------------- internal/private.proto | 31 +- pilosa.go | 4 +- server.go | 64 ++-- server/cluster_test.go | 6 +- server/server.go | 13 +- test/cluster.go | 54 +-- test/executor.go | 2 +- test/handler.go | 13 +- uri.go | 10 + 27 files changed, 1145 insertions(+), 869 deletions(-) diff --git a/broadcast.go b/broadcast.go index 7d00f1107..883b62436 100644 --- a/broadcast.go +++ b/broadcast.go @@ -24,11 +24,9 @@ import ( // MemberSet represents an interface for Node membership and inter-node communication. type MemberSet interface { - // Returns a list of all Nodes in the cluster - Nodes() []*Node - // Open starts any network activity implemented by the MemberSet - Open() error + // Node is the local node, used for membership broadcasts. + Open(n *Node) error } // StaticMemberSet represents a basic MemberSet for testing. @@ -41,13 +39,8 @@ func NewStaticMemberSet() *StaticMemberSet { return &StaticMemberSet{} } -// Nodes implements the MemberSet interface and returns a list of nodes in the cluster. -func (s *StaticMemberSet) Nodes() []*Node { - return s.nodes -} - // Open implements the MemberSet interface to start network activity, but for a static MemberSet it does nothing. -func (s *StaticMemberSet) Open() error { +func (s *StaticMemberSet) Open(n *Node) error { return nil } diff --git a/client_test.go b/client_test.go index 17aafd7f4..f2bd18e50 100644 --- a/client_test.go +++ b/client_test.go @@ -36,10 +36,10 @@ func createCluster(c *pilosa.Cluster) ([]*test.Server, []*test.Holder) { for i := 0; i < numNodes; i++ { hldr[i] = test.MustOpenHolder() server[i] = test.NewServer() - server[i].Handler.URI = server[i].HostURI() server[i].Handler.Cluster = c server[i].Handler.Cluster.Nodes[i].URI = server[i].HostURI() server[i].Handler.Holder = hldr[i].Holder + server[i].Handler.Node = server[i].Handler.Cluster.Nodes[i] } return server, hldr } @@ -64,21 +64,21 @@ func TestClient_MultiNode(t *testing.T) { s[0].Handler.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) { e := pilosa.NewExecutor(defaultClient) e.Holder = hldr[0].Holder - e.URI = cluster.Nodes[0].URI + e.Node = cluster.Nodes[0] e.Cluster = cluster return e.Execute(ctx, index, query, slices, opt) } s[1].Handler.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) { e := pilosa.NewExecutor(defaultClient) e.Holder = hldr[1].Holder - e.URI = cluster.Nodes[1].URI + e.Node = cluster.Nodes[1] e.Cluster = cluster return e.Execute(ctx, index, query, slices, opt) } s[2].Handler.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) { e := pilosa.NewExecutor(defaultClient) e.Holder = hldr[2].Holder - e.URI = cluster.Nodes[2].URI + e.Node = cluster.Nodes[2] e.Cluster = cluster return e.Execute(ctx, index, query, slices, opt) } @@ -217,10 +217,10 @@ func TestClient_Import(t *testing.T) { s := test.NewServer() defer s.Close() - s.Handler.URI = s.HostURI() s.Handler.Cluster = test.NewCluster(1) s.Handler.Cluster.Nodes[0].URI = s.HostURI() s.Handler.Holder = hldr.Holder + s.Handler.Node = s.Handler.Cluster.Nodes[0] // Send import request. c := test.MustNewClient(s.Host(), defaultClient) @@ -268,10 +268,10 @@ func TestClient_ImportInverseEnabled(t *testing.T) { s := test.NewServer() defer s.Close() - s.Handler.URI = s.HostURI() s.Handler.Cluster = test.NewCluster(1) s.Handler.Cluster.Nodes[0].URI = s.HostURI() s.Handler.Holder = hldr.Holder + s.Handler.Node = s.Handler.Cluster.Nodes[0] // Send import request. c := test.MustNewClient(s.Host(), defaultClient) @@ -317,10 +317,10 @@ func TestClient_ImportValue(t *testing.T) { s := test.NewServer() defer s.Close() - s.Handler.URI = s.HostURI() s.Handler.Cluster = test.NewCluster(1) s.Handler.Cluster.Nodes[0].URI = s.HostURI() s.Handler.Holder = hldr.Holder + s.Handler.Node = s.Handler.Cluster.Nodes[0] // Send import request. c := test.MustNewClient(s.Host(), defaultClient) @@ -355,10 +355,10 @@ func TestClient_BackupRestore(t *testing.T) { s := test.NewServer() defer s.Close() - s.Handler.URI = s.HostURI() s.Handler.Cluster = test.NewCluster(1) s.Handler.Cluster.Nodes[0].URI = s.HostURI() s.Handler.Holder = hldr.Holder + s.Handler.Node = s.Handler.Cluster.Nodes[0] c := test.MustNewClient(s.Host(), defaultClient) @@ -420,10 +420,10 @@ func TestClient_BackupInverseView(t *testing.T) { s := test.NewServer() defer s.Close() - s.Handler.URI = s.HostURI() s.Handler.Cluster = test.NewCluster(1) s.Handler.Cluster.Nodes[0].URI = s.HostURI() s.Handler.Holder = hldr.Holder + s.Handler.Node = s.Handler.Cluster.Nodes[0] c := test.MustNewClient(s.Host(), defaultClient) @@ -457,10 +457,10 @@ func TestClient_BackupInvalidView(t *testing.T) { s := test.NewServer() defer s.Close() - s.Handler.URI = s.HostURI() s.Handler.Cluster = test.NewCluster(1) s.Handler.Cluster.Nodes[0].URI = s.HostURI() s.Handler.Holder = hldr.Holder + s.Handler.Node = s.Handler.Cluster.Nodes[0] c := test.MustNewClient(s.Host(), defaultClient) @@ -486,10 +486,10 @@ func TestClient_FragmentBlocks(t *testing.T) { s := test.NewServer() defer s.Close() - s.Handler.URI = s.HostURI() s.Handler.Cluster = test.NewCluster(1) s.Handler.Cluster.Nodes[0].URI = s.HostURI() s.Handler.Holder = hldr.Holder + s.Handler.Node = s.Handler.Cluster.Nodes[0] // Retrieve blocks. c := test.MustNewClient(s.Host(), defaultClient) diff --git a/cluster.go b/cluster.go index b2ed0e372..1ed810ea0 100644 --- a/cluster.go +++ b/cluster.go @@ -66,7 +66,47 @@ const ( // Node represents a node in the cluster. type Node struct { - URI URI `json:"uri"` + ID string `json:"id"` + URI URI `json:"uri"` +} + +func (n Node) String() string { + return fmt.Sprintf("Node: %s", n.ID) +} + +// EncodeNodes converts a into its internal representation. +func EncodeNodes(a []*Node) []*internal.Node { + other := make([]*internal.Node, len(a)) + for i := range a { + other[i] = EncodeNode(a[i]) + } + return other +} + +// EncodeNode converts n into its internal representation. +func EncodeNode(n *Node) *internal.Node { + return &internal.Node{ + ID: n.ID, + URI: n.URI.Encode(), + } +} + +func DecodeNodes(a []*internal.Node) []*Node { + if len(a) == 0 { + return nil + } + other := make([]*Node, len(a)) + for i := range a { + other[i] = DecodeNode(a[i]) + } + return other +} + +func DecodeNode(node *internal.Node) *Node { + return &Node{ + ID: node.ID, + URI: decodeURI(node.URI), + } } // Nodes represents a list of nodes. @@ -82,10 +122,10 @@ func (a Nodes) Contains(n *Node) bool { return false } -// ContainsURI returns true if host matches one of the node's uri. -func (a Nodes) ContainsURI(uri URI) bool { +// ContainsID returns true if host matches one of the node's id. +func (a Nodes) ContainsID(id string) bool { for _, n := range a { - if n.URI == uri { + if n.ID == id { return true } } @@ -103,6 +143,17 @@ func (a Nodes) Filter(n *Node) []*Node { return other } +// FilterID returns a new list of nodes with ID removed. +func (a Nodes) FilterID(id string) []*Node { + other := make([]*Node, 0, len(a)) + for _, node := range a { + if node.ID != id { + other = append(other, node) + } + } + return other +} + // FilterURI returns a new list of nodes with URI removed. func (a Nodes) FilterURI(uri URI) []*Node { other := make([]*Node, 0, len(a)) @@ -114,6 +165,15 @@ func (a Nodes) FilterURI(uri URI) []*Node { return other } +// IDs returns a list of all node IDs. +func (a Nodes) IDs() []string { + ids := make([]string, len(a)) + for i, n := range a { + ids[i] = n.ID + } + return ids +} + // URIs returns a list of all uris. func (a Nodes) URIs() []URI { uris := make([]URI, len(a)) @@ -130,24 +190,24 @@ func (a Nodes) Clone() []*Node { return other } -// ByHost implements sort.Interface for []Node based on -// the Host field. -type ByHost []*Node +// byID implements sort.Interface for []Node based on +// the ID field. +type byID []*Node -func (h ByHost) Len() int { return len(h) } -func (h ByHost) Swap(i, j int) { h[i], h[j] = h[j], h[i] } -func (h ByHost) Less(i, j int) bool { return h[i].URI.String() < h[j].URI.String() } +func (h byID) Len() int { return len(h) } +func (h byID) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h byID) Less(i, j int) bool { return h[i].ID < h[j].ID } // nodeAction represents a node that is joining or leaving the cluster. type nodeAction struct { - uri URI + node *Node action string } // Cluster represents a collection of nodes. type Cluster struct { ID string - URI URI + Node *Node Nodes []*Node // TODO phase this out? MemberSet MemberSet @@ -227,16 +287,33 @@ func (c *Cluster) logger() *log.Logger { return log.New(c.LogOutput, "", log.LstdFlags) } +// Coordinator returns the coordinator node. +func (c *Cluster) CoordinatorNode() *Node { + return c.nodeByURI(c.Coordinator) +} + // IsCoordinator is true if this node is the coordinator. func (c *Cluster) IsCoordinator() bool { - return c.Static || c.Coordinator == c.URI + return c.Static || c.Coordinator == c.Node.URI } // SetCoordinator updates the Coordinator to new if it is // currently old. Returns true if the Coordinator changed. -func (c *Cluster) SetCoordinator(oldURI, newURI URI) bool { - if c.Coordinator == oldURI && oldURI != newURI { - c.Coordinator = newURI +func (c *Cluster) SetCoordinator(o, n *Node) bool { + // Get old node. + oldNode := c.nodeByID(o.ID) + if oldNode == nil { + return false + } + + // Get new node. + newNode := c.nodeByID(n.ID) + if newNode == nil { + return false + } + + if c.Coordinator == oldNode.URI && oldNode != newNode { + c.Coordinator = newNode.URI return true } return false @@ -244,12 +321,11 @@ func (c *Cluster) SetCoordinator(oldURI, newURI URI) bool { // AddNode adds a node to the Cluster and updates and saves the // new topology. -func (c *Cluster) AddNode(uri URI) error { - c.logger().Printf("add node %s to cluster on %s", uri, c.URI) +func (c *Cluster) AddNode(node *Node) error { + c.logger().Printf("add node %s to cluster on %s", node, c.Node) // add to cluster - _, added := c.addNodeBasicSorted(uri) - if !added { + if !c.addNodeBasicSorted(node) { return nil } @@ -257,7 +333,7 @@ func (c *Cluster) AddNode(uri URI) error { if c.Topology == nil { return fmt.Errorf("Cluster.Topology is nil") } - if !c.Topology.AddURI(uri) { + if !c.Topology.AddID(node.ID) { return nil } @@ -267,10 +343,9 @@ func (c *Cluster) AddNode(uri URI) error { // RemoveNode removes a node from the Cluster and updates and saves the // new topology. -func (c *Cluster) RemoveNode(uri URI) error { +func (c *Cluster) RemoveNode(node *Node) error { // remove from cluster - removed := c.removeNodeBasicSorted(uri) - if !removed { + if !c.removeNodeBasicSorted(node) { return nil } @@ -278,7 +353,7 @@ func (c *Cluster) RemoveNode(uri URI) error { if c.Topology == nil { return fmt.Errorf("Cluster.Topology is nil") } - if !c.Topology.RemoveURI(uri) { + if !c.Topology.RemoveID(node.ID) { return nil } @@ -286,9 +361,9 @@ func (c *Cluster) RemoveNode(uri URI) error { return c.saveTopology() } -// NodeSet returns the list of uris in the cluster. -func (c *Cluster) NodeSet() []URI { - return Nodes(c.Nodes).URIs() +// NodeIDs returns the list of IDs in the cluster. +func (c *Cluster) NodeIDs() []string { + return Nodes(c.Nodes).IDs() } func (c *Cluster) setID(id string) { @@ -310,8 +385,8 @@ func (c *Cluster) State() string { func (c *Cluster) SetState(state string) { c.mu.Lock() - defer c.mu.Unlock() c.setState(state) + c.mu.Unlock() } func (c *Cluster) setState(state string) { @@ -320,7 +395,7 @@ func (c *Cluster) setState(state string) { return } - c.logger().Printf("change cluster state from %s to %s on %s", c.State, state, c.URI) + c.logger().Printf("change cluster state from %s to %s on %s", c.state, state, c.Node.ID) var doCleanup bool @@ -345,7 +420,7 @@ func (c *Cluster) setState(state string) { // It's safe to do a cleanup after state changes back to normal. if doCleanup { var cleaner HolderCleaner - cleaner.URI = c.URI + cleaner.Node = c.Node cleaner.Holder = c.Holder cleaner.Cluster = c cleaner.Closing = c.closing @@ -359,17 +434,17 @@ func (c *Cluster) setState(state string) { func (c *Cluster) SetNodeState(state string) error { if c.IsCoordinator() { - return c.ReceiveNodeState(c.URI, state) + return c.ReceiveNodeState(c.Node.ID, state) } // Send node state to coordinator. ns := &internal.NodeStateMessage{ - URI: c.URI.Encode(), - State: state, + NodeID: c.Node.ID, + State: state, } c.logger().Printf("Sending State %s (%s)", state, c.Coordinator) - if err := c.sendTo(c.Coordinator, ns); err != nil { + if err := c.sendTo(c.CoordinatorNode(), ns); err != nil { return fmt.Errorf("sending node state error: err=%s", err) } @@ -379,7 +454,7 @@ func (c *Cluster) SetNodeState(state string) error { // ReceiveNodeState sets node state in Topology in order for the // Coordinator to keep track of, during startup, which nodes have // finished opening their Holder. -func (c *Cluster) ReceiveNodeState(uri URI, state string) error { +func (c *Cluster) ReceiveNodeState(nodeID string, state string) error { if !c.IsCoordinator() { return nil } @@ -389,8 +464,8 @@ func (c *Cluster) ReceiveNodeState(uri URI, state string) error { return nil } - c.Topology.nodeStates[uri] = state - c.logger().Printf("received state %s (%s)", state, uri) + c.Topology.nodeStates[nodeID] = state + c.logger().Printf("received state %s (%s)", state, nodeID) // Set cluster state to NORMAL. if c.haveTopologyAgreement() && c.allNodesReady() { @@ -410,12 +485,22 @@ func (c *Cluster) Status() *internal.ClusterStatus { return &internal.ClusterStatus{ ClusterID: c.ID, State: c.state, - NodeSet: encodeURIs(c.NodeSet()), + Nodes: EncodeNodes(c.Nodes), } } -// NodeByURI returns a node reference by uri. -func (c *Cluster) NodeByURI(uri URI) *Node { +// nodeByID returns a node reference by ID. +func (c *Cluster) nodeByID(id string) *Node { + for _, n := range c.Nodes { + if n.ID == id { + return n + } + } + return nil +} + +// nodeByURI returns a node reference by node URI. +func (c *Cluster) nodeByURI(uri URI) *Node { for _, n := range c.Nodes { if n.URI == uri { return n @@ -424,37 +509,36 @@ func (c *Cluster) NodeByURI(uri URI) *Node { return nil } -// nodePositionByURI returns the position of the node in slice c.Nodes. -func (c *Cluster) nodePositionByURI(uri URI) int { +// nodePositionByID returns the position of the node in slice c.Nodes. +func (c *Cluster) nodePositionByID(nodeID string) int { for i, n := range c.Nodes { - if n.URI == uri { + if n.ID == nodeID { return i } } return -1 } -// addNodeBasicSorted adds a node to the cluster, sorted by uri. +// addNodeBasicSorted adds a node to the cluster, sorted by id. // Returns a pointer to the node and true if the node was added. -func (c *Cluster) addNodeBasicSorted(uri URI) (*Node, bool) { - n := c.NodeByURI(uri) +func (c *Cluster) addNodeBasicSorted(node *Node) bool { + n := c.nodeByID(node.ID) if n != nil { - return n, false + return false } - n = &Node{URI: uri} - c.Nodes = append(c.Nodes, n) + c.Nodes = append(c.Nodes, node) // All hosts must be merged in the same order on all nodes in the cluster. - sort.Sort(ByHost(c.Nodes)) + sort.Sort(byID(c.Nodes)) - return n, true + return true } // removeNodeBasicSorted removes a node from the cluster, maintaining // the sort order. Returns true if the node was removed. -func (c *Cluster) removeNodeBasicSorted(uri URI) bool { - i := c.nodePositionByURI(uri) +func (c *Cluster) removeNodeBasicSorted(node *Node) bool { + i := c.nodePositionByID(node.ID) if i < 0 { return false } @@ -492,7 +576,7 @@ func fragsDiff(a, b []frag) []frag { return ret } -type fragsByHost map[URI][]frag +type fragsByHost map[string][]frag func (a fragsByHost) add(b fragsByHost) fragsByHost { for k, v := range b { @@ -539,7 +623,7 @@ func (c *Cluster) fragCombos(idx string, maxSlice uint64, frameViews viewsByFram // for each frame/view combination: for frame, views := range frameViews { for _, view := range views { - t[n.URI] = append(t[n.URI], frag{frame, view, i}) + t[n.ID] = append(t[n.ID], frag{frame, view, i}) } } } @@ -550,57 +634,57 @@ func (c *Cluster) fragCombos(idx string, maxSlice uint64, frameViews viewsByFram // diff compares c with another cluster and determines if a node is being // added or removed. An error is returned for any case other than where // exactly one node is added or removed. -func (c *Cluster) diff(other *Cluster) (action string, uri URI, err error) { +func (c *Cluster) diff(other *Cluster) (action string, nodeID string, err error) { lenFrom := len(c.Nodes) lenTo := len(other.Nodes) // Determine if a node is being added or removed. if lenFrom == lenTo { - return action, uri, errors.New("clusters are the same size") + return action, nodeID, errors.New("clusters are the same size") } if lenFrom < lenTo { // Adding a node. if lenTo-lenFrom > 1 { - return action, uri, errors.New("adding more than one node at a time is not supported") + return action, nodeID, errors.New("adding more than one node at a time is not supported") } action = ResizeJobActionAdd - // Determine the URI that is being added. + // Determine the node ID that is being added. for _, n := range other.Nodes { - if c.NodeByURI(n.URI) == nil { - uri = n.URI + if c.nodeByID(n.ID) == nil { + nodeID = n.ID break } } } else if lenFrom > lenTo { // Removing a node. if lenFrom-lenTo > 1 { - return action, uri, errors.New("removing more than one node at a time is not supported") + return action, nodeID, errors.New("removing more than one node at a time is not supported") } action = ResizeJobActionRemove - // Determine the URI that is being removed. + // Determine the node ID that is being removed. for _, n := range c.Nodes { - if other.NodeByURI(n.URI) == nil { - uri = n.URI + if other.nodeByID(n.ID) == nil { + nodeID = n.ID break } } } - return action, uri, nil + return action, nodeID, nil } // fragSources returns a list of ResizeSources - for each node in the `to` cluster - // required to move from cluster `c` to cluster `to`. -func (c *Cluster) fragSources(to *Cluster, idx *Index) (map[URI][]*internal.ResizeSource, error) { - m := make(map[URI][]*internal.ResizeSource) +func (c *Cluster) fragSources(to *Cluster, idx *Index) (map[string][]*internal.ResizeSource, error) { + m := make(map[string][]*internal.ResizeSource) // Determine if a node is being added or removed. - action, diffURI, err := c.diff(to) + action, diffNodeID, err := c.diff(to) if err != nil { return nil, err } // Initialize the map with all the nodes in `to`. for _, n := range to.Nodes { - m[n.URI] = nil + m[n.ID] = nil } // If a node is being added, the source can be confined to the @@ -625,50 +709,50 @@ func (c *Cluster) fragSources(to *Cluster, idx *Index) (map[URI][]*internal.Resi // srcFrags is the frag map based on a source cluster of replica = 1. srcFrags := srcCluster.fragsByHost(idx) - // srcHostsByFrag is the inverse representation of srcFrags. - srcHostsByFrag := make(map[frag]URI) - for uri, frags := range srcFrags { + // srcNodesByFrag is the inverse representation of srcFrags. + srcNodesByFrag := make(map[frag]string) + for nodeID, frags := range srcFrags { // If a node is being removed, don't consider it as a source. - if action == ResizeJobActionRemove && uri == diffURI { + if action == ResizeJobActionRemove && nodeID == diffNodeID { continue } for _, frag := range frags { - srcHostsByFrag[frag] = uri + srcNodesByFrag[frag] = nodeID } } - // Get the frag diff for each host. + // Get the frag diff for each nodeID. diffs := make(fragsByHost) - for host, frags := range tFrags { - if _, ok := fFrags[host]; ok { - diffs[host] = fragsDiff(frags, fFrags[host]) + for nodeID, frags := range tFrags { + if _, ok := fFrags[nodeID]; ok { + diffs[nodeID] = fragsDiff(frags, fFrags[nodeID]) } else { - diffs[host] = frags + diffs[nodeID] = frags } } // Get the ResizeSource for each diff. - for host, diff := range diffs { - m[host] = []*internal.ResizeSource{} + for nodeID, diff := range diffs { + m[nodeID] = []*internal.ResizeSource{} for _, frag := range diff { - // If there is no valid source URI for a fragment, + // If there is no valid source node ID for a fragment, // it likely means that the replica factor was not // high enough for the remaining nodes to contain // the fragment. - srcHost, ok := srcHostsByFrag[frag] + srcNodeID, ok := srcNodesByFrag[frag] if !ok { return nil, errors.New("not enough data to perform resize") } src := &internal.ResizeSource{ - URI: (srcHost).Encode(), + Node: EncodeNode(c.nodeByID(srcNodeID)), Index: idx.Name(), Frame: frag.frame, View: frag.view, Slice: frag.slice, } - m[host] = append(m[host], src) + m[nodeID] = append(m[nodeID], src) } } @@ -693,8 +777,8 @@ func (c *Cluster) FragmentNodes(index string, slice uint64) []*Node { } // OwnsFragment returns true if a host owns a fragment. -func (c *Cluster) OwnsFragment(uri URI, index string, slice uint64) bool { - return Nodes(c.FragmentNodes(index, slice)).ContainsURI(uri) +func (c *Cluster) OwnsFragment(nodeID string, index string, slice uint64) bool { + return Nodes(c.FragmentNodes(index, slice)).ContainsID(nodeID) } // PartitionNodes returns a list of nodes that own a partition. @@ -735,14 +819,14 @@ func (c *Cluster) OwnsSlices(index string, maxSlice uint64, uri URI) []uint64 { } // ContainsSlices is like OwnsSlices, but it includes replicas. -func (c *Cluster) ContainsSlices(index string, maxSlice uint64, uri URI) []uint64 { +func (c *Cluster) ContainsSlices(index string, maxSlice uint64, node *Node) []uint64 { var slices []uint64 for i := uint64(0); i <= maxSlice; i++ { p := c.Partition(index, i) // Determine the nodes for partition. nodes := c.PartitionNodes(p) - for _, node := range nodes { - if node.URI == uri { + for _, n := range nodes { + if n.ID == node.ID { slices = append(slices, i) } } @@ -793,7 +877,7 @@ func (c *Cluster) Open() error { } // Add the local node to the cluster. - c.AddNode(c.URI) + c.AddNode(c.Node) // Start the EventReceiver. if err := c.EventReceiver.Start(c); err != nil { @@ -801,7 +885,7 @@ func (c *Cluster) Open() error { } // Open MemberSet communication. - if err := c.MemberSet.Open(); err != nil { + if err := c.MemberSet.Open(c.Node); err != nil { return fmt.Errorf("opening MemberSet: %v", err) } @@ -832,21 +916,21 @@ func (c *Cluster) markAsJoined() { } func (c *Cluster) needTopologyAgreement() bool { - return c.State() == ClusterStateStarting && !URISlicesAreEqual(c.Topology.NodeSet, c.NodeSet()) + return c.State() == ClusterStateStarting && !StringSlicesAreEqual(c.Topology.NodeIDs, c.NodeIDs()) } func (c *Cluster) haveTopologyAgreement() bool { if c.Static { return true } - return URISlicesAreEqual(c.Topology.NodeSet, c.NodeSet()) + return StringSlicesAreEqual(c.Topology.NodeIDs, c.NodeIDs()) } func (c *Cluster) allNodesReady() bool { if c.Static { return true } - for _, uri := range c.Topology.NodeSet { + for _, uri := range c.Topology.NodeIDs { if c.Topology.nodeStates[uri] != NodeStateReady { return false } @@ -885,9 +969,9 @@ func (c *Cluster) handleNodeAction(nodeAction nodeAction) error { } // Add/remove uri to/from the cluster. if j.action == ResizeJobActionRemove { - return c.RemoveNode(nodeAction.uri) + return c.RemoveNode(nodeAction.node) } else if j.action == ResizeJobActionAdd { - return c.AddNode(nodeAction.uri) + return c.AddNode(nodeAction.node) } case ResizeJobStateAborted: if err := c.CompleteCurrentJob(ResizeJobStateAborted); err != nil { @@ -904,8 +988,7 @@ func (c *Cluster) setStateAndBroadcast(state string) error { return c.Broadcaster.SendSync(c.Status()) } -func (c *Cluster) sendTo(to URI, msg proto.Message) error { - node := &Node{URI: to} +func (c *Cluster) sendTo(node *Node, msg proto.Message) error { if err := c.Broadcaster.SendTo(node, msg); err != nil { return err } @@ -991,8 +1074,7 @@ func (c *Cluster) generateResizeJob(nodeAction nodeAction) (*ResizeJob, error) { // Broadcaster is associated to the ResizeJob here for use in broadcasting // the resize instructions to other nodes in the cluster. func (c *Cluster) generateResizeJobByAction(nodeAction nodeAction) (*ResizeJob, error) { - - j := NewResizeJob(Nodes(c.Nodes).URIs(), nodeAction.uri, nodeAction.action) + j := NewResizeJob(c.Nodes, nodeAction.node, nodeAction.action) j.Broadcaster = c.Broadcaster // toCluster is a clone of Cluster with the new node added/removed for comparison. @@ -1002,16 +1084,16 @@ func (c *Cluster) generateResizeJobByAction(nodeAction nodeAction) (*ResizeJob, toCluster.PartitionN = c.PartitionN toCluster.ReplicaN = c.ReplicaN if nodeAction.action == ResizeJobActionRemove { - toCluster.removeNodeBasicSorted(nodeAction.uri) + toCluster.removeNodeBasicSorted(nodeAction.node) } else if nodeAction.action == ResizeJobActionAdd { - toCluster.addNodeBasicSorted(nodeAction.uri) + toCluster.addNodeBasicSorted(nodeAction.node) } // multiIndex is a map of sources initialized with all the nodes in toCluster. - multiIndex := make(map[URI][]*internal.ResizeSource) + multiIndex := make(map[string][]*internal.ResizeSource) for _, n := range toCluster.Nodes { - multiIndex[n.URI] = nil + multiIndex[n.ID] = nil } // Add to multiIndex the instructions for each index. @@ -1021,23 +1103,23 @@ func (c *Cluster) generateResizeJobByAction(nodeAction nodeAction) (*ResizeJob, return nil, err } - for u, sources := range fragSources { + for id, sources := range fragSources { for _, src := range sources { - multiIndex[u] = append(multiIndex[u], src) + multiIndex[id] = append(multiIndex[id], src) } } } - for u, sources := range multiIndex { + for id, sources := range multiIndex { // If a host doesn't need to request data, mark it as complete. if len(sources) == 0 { - j.URIs[u] = true + j.IDs[id] = true continue } instr := &internal.ResizeInstruction{ JobID: j.ID, - URI: u.Encode(), - Coordinator: encodeURI(c.Coordinator), + Node: EncodeNode(toCluster.nodeByID(id)), + Coordinator: EncodeNode(c.CoordinatorNode()), Sources: sources, Schema: c.Holder.EncodeSchema(), // Include the schema to ensure it's in sync on the receiving node. ClusterStatus: c.Status(), @@ -1063,7 +1145,7 @@ func (c *Cluster) CompleteCurrentJob(state string) error { // FollowResizeInstruction is run by any node that receives a ResizeInstruction. func (c *Cluster) FollowResizeInstruction(instr *internal.ResizeInstruction) error { - c.logger().Printf("follow resize instruction on %s", c.URI) + c.logger().Printf("follow resize instruction on %s", c.Node.ID) // Make sure the cluster status on this node agrees with the Coordinator // before attempting a resize. if err := c.MergeClusterStatus(instr.ClusterStatus); err != nil { @@ -1082,7 +1164,7 @@ func (c *Cluster) FollowResizeInstruction(instr *internal.ResizeInstruction) err // Prepare the return message. complete := &internal.ResizeInstructionComplete{ JobID: instr.JobID, - URI: instr.URI, + Node: instr.Node, Error: "", } @@ -1096,13 +1178,13 @@ func (c *Cluster) FollowResizeInstruction(instr *internal.ResizeInstruction) err } // Create a client for calling remote nodes. - client := NewInternalHTTPClientFromURI(&c.URI, c.RemoteClient) // TODO: ClientOptions + client := NewInternalHTTPClientFromURI(&c.Node.URI, c.RemoteClient) // TODO: ClientOptions // Request each source file in ResizeSources. for _, src := range instr.Sources { - c.logger().Printf("get slice %d for index %s from host %s", src.Slice, src.Index, src.URI) + c.logger().Printf("get slice %d for index %s from host %s", src.Slice, src.Index, src.Node.URI) - srcURI := decodeURI(src.URI) + srcURI := decodeURI(src.Node.URI) // Retrieve frame. f := c.Holder.Frame(src.Index, src.Frame) @@ -1123,7 +1205,7 @@ func (c *Cluster) FollowResizeInstruction(instr *internal.ResizeInstruction) err } // Stream slice from remote node. - c.logger().Printf("retrieve slice %d for index %s from host %s", src.Slice, src.Index, src.URI) + c.logger().Printf("retrieve slice %d for index %s from host %s", src.Slice, src.Index, src.Node.URI) rd, err := client.RetrieveSliceFromURI(context.Background(), src.Index, src.Frame, src.View, src.Slice, srcURI) if err != nil { // For now it is an acceptable error if the fragment is not found @@ -1137,7 +1219,7 @@ func (c *Cluster) FollowResizeInstruction(instr *internal.ResizeInstruction) err } return err } else if rd == nil { - return fmt.Errorf("slice %v doesn't exist on host: %s", src.Slice, src.URI) + return fmt.Errorf("slice %v doesn't exist on host: %s", src.Slice, src.Node.URI) } // Write to local frame and always close reader. @@ -1156,7 +1238,7 @@ func (c *Cluster) FollowResizeInstruction(instr *internal.ResizeInstruction) err complete.Error = err.Error() } - if err := c.sendTo(decodeURI(instr.Coordinator), complete); err != nil { + if err := c.sendTo(DecodeNode(instr.Coordinator), complete); err != nil { c.logger().Printf("sending resizeInstructionComplete error: err=%s", err) } }() @@ -1180,12 +1262,10 @@ func (c *Cluster) MarkResizeInstructionComplete(complete *internal.ResizeInstruc return fmt.Errorf("ResizeJob %d is no longer running", j.ID) } - uri := decodeURI(complete.URI) - // Mark host complete. - j.URIs[uri] = true + j.IDs[complete.Node.ID] = true - if !j.urisArePending() { + if !j.nodesArePending() { j.result <- ResizeJobStateDone } @@ -1203,7 +1283,7 @@ func (c *Cluster) job(id int64) *ResizeJob { return c.jobs[id] } type ResizeJob struct { ID int64 - URIs map[URI]bool + IDs map[string]bool Instructions []*internal.ResizeInstruction Broadcaster Broadcaster @@ -1223,32 +1303,32 @@ func (j *ResizeJob) logger() *log.Logger { } // NewResizeJob returns a new instance of ResizeJob. -func NewResizeJob(existingURIs []URI, uri URI, action string) *ResizeJob { +func NewResizeJob(existingNodes []*Node, node *Node, action string) *ResizeJob { // Build a map of uris to track their resize status. // The value for a node will be set to true after that node // has indicated that it has completed all resize instructions. - uris := make(map[URI]bool) + ids := make(map[string]bool) if action == ResizeJobActionRemove { - for _, u := range existingURIs { + for _, n := range existingNodes { // Exclude the removed node from the map. - if u == uri { + if n.ID == node.ID { continue } - uris[u] = false + ids[n.ID] = false } } else if action == ResizeJobActionAdd { - for _, u := range existingURIs { - uris[u] = false + for _, n := range existingNodes { + ids[n.ID] = false } // Include the added node in the map for tracking. - uris[uri] = false + ids[node.ID] = false } return &ResizeJob{ ID: rand.Int63(), - URIs: uris, + IDs: ids, action: action, result: make(chan string), LogOutput: os.Stderr, @@ -1280,7 +1360,7 @@ func (j *ResizeJob) Run() error { j.SetState(ResizeJobStateRunning) // Job can be considered done in the case where it doesn't require any action. - if !j.urisArePending() { + if !j.nodesArePending() { j.logger().Printf("ResizeJob contains no pending tasks; mark as done") j.result <- ResizeJobStateDone return nil @@ -1305,9 +1385,9 @@ func (j *ResizeJob) isComplete() bool { } } -// urisArePending returns true if any uri is still working on the resize. -func (j *ResizeJob) urisArePending() bool { - for _, complete := range j.URIs { +// nodesArePending returns true if any node is still working on the resize. +func (j *ResizeJob) nodesArePending() bool { + for _, complete := range j.IDs { if !complete { return true } @@ -1322,7 +1402,8 @@ func (j *ResizeJob) distributeResizeInstructions() error { // Because the node may not be in the cluster yet, create // a dummy node object to use in the SendTo() method. node := &Node{ - URI: decodeURI(instr.URI), + ID: instr.Node.ID, + URI: decodeURI(instr.Node.URI), } j.logger().Printf("send resize instructions: %v", instr) if err := j.Broadcaster.SendTo(node, instr); err != nil { @@ -1332,32 +1413,16 @@ func (j *ResizeJob) distributeResizeInstructions() error { return nil } -type NodeSet []URI +type NodeIDs []string -func (n NodeSet) Len() int { return len(n) } -func (n NodeSet) Swap(i, j int) { n[i], n[j] = n[j], n[i] } -func (n NodeSet) Less(i, j int) bool { return n[i].String() < n[j].String() } +func (n NodeIDs) Len() int { return len(n) } +func (n NodeIDs) Swap(i, j int) { n[i], n[j] = n[j], n[i] } +func (n NodeIDs) Less(i, j int) bool { return n[i] < n[j] } -func (u NodeSet) ToHostPortStrings() []string { - other := make([]string, 0, len(u)) - for _, uri := range u { - other = append(other, uri.HostPort()) - } - return other -} - -func (u NodeSet) ToStrings() []string { - other := make([]string, 0, len(u)) - for _, uri := range u { - other = append(other, uri.String()) - } - return other -} - -// ContainsURI returns true if uri matches one of the nodesets's uris. -func (n NodeSet) ContainsURI(uri URI) bool { - for _, nuri := range n { - if nuri == uri { +// ContainsID returns true if idi matches one of the nodesets's IDs. +func (n NodeIDs) ContainsID(id string) bool { + for _, nid := range n { + if nid == id { return true } } @@ -1367,71 +1432,71 @@ func (n NodeSet) ContainsURI(uri URI) bool { // Topology represents the list of hosts in the cluster. type Topology struct { mu sync.RWMutex - NodeSet []URI + NodeIDs []string ClusterID string // nodeStates holds the state of each node according to // the coordinator. Used during startup and data load. - nodeStates map[URI]string + nodeStates map[string]string } func NewTopology() *Topology { return &Topology{ - nodeStates: make(map[URI]string), + nodeStates: make(map[string]string), } } -// ContainsURI returns true if uri matches one of the topology's uris. -func (t *Topology) ContainsURI(uri URI) bool { +// ContainsID returns true if id matches one of the topology's IDs. +func (t *Topology) ContainsID(id string) bool { t.mu.RLock() defer t.mu.RUnlock() - return t.containsURI(uri) + return t.containsID(id) } -func (t *Topology) containsURI(uri URI) bool { - return NodeSet(t.NodeSet).ContainsURI(uri) +func (t *Topology) containsID(id string) bool { + return NodeIDs(t.NodeIDs).ContainsID(id) } -func (t *Topology) positionByURI(uri URI) int { - for i, turi := range t.NodeSet { - if turi == uri { +func (t *Topology) positionByID(nodeID string) int { + for i, tid := range t.NodeIDs { + if tid == nodeID { return i } } return -1 } -// AddURI adds the uri to the topology and returns true if added. -func (t *Topology) AddURI(uri URI) bool { +// AddID adds the node ID to the topology and returns true if added. +func (t *Topology) AddID(nodeID string) bool { t.mu.Lock() defer t.mu.Unlock() - if t.containsURI(uri) { + if t.containsID(nodeID) { return false } - t.NodeSet = append(t.NodeSet, uri) + t.NodeIDs = append(t.NodeIDs, nodeID) - sort.Slice(t.NodeSet, + sort.Slice(t.NodeIDs, func(i, j int) bool { - return t.NodeSet[i].String() < t.NodeSet[j].String() + return t.NodeIDs[i] < t.NodeIDs[j] }) return true } -// RemoveURI removes the uri from the topology and returns true if removed. -func (t *Topology) RemoveURI(uri URI) bool { +// RemoveID removes the node ID from the topology and returns true if removed. +func (t *Topology) RemoveID(nodeID string) bool { t.mu.Lock() defer t.mu.Unlock() - i := t.positionByURI(uri) + i := t.positionByID(nodeID) if i < 0 { return false } - copy(t.NodeSet[i:], t.NodeSet[i+1:]) - t.NodeSet[len(t.NodeSet)-1] = URI{} - t.NodeSet = t.NodeSet[:len(t.NodeSet)-1] + copy(t.NodeIDs[i:], t.NodeIDs[i+1:]) + t.NodeIDs[len(t.NodeIDs)-1] = "" + t.NodeIDs = t.NodeIDs[:len(t.NodeIDs)-1] return true } @@ -1485,7 +1550,7 @@ func encodeTopology(topology *Topology) *internal.Topology { } return &internal.Topology{ ClusterID: topology.ClusterID, - NodeSet: encodeURIs(topology.NodeSet), + NodeIDs: topology.NodeIDs, } } @@ -1496,19 +1561,16 @@ func decodeTopology(topology *internal.Topology) (*Topology, error) { t := NewTopology() t.ClusterID = topology.ClusterID - t.NodeSet = decodeURIs(topology.NodeSet) - sort.Slice(t.NodeSet, + t.NodeIDs = topology.NodeIDs + sort.Slice(t.NodeIDs, func(i, j int) bool { - return t.NodeSet[i].String() < t.NodeSet[j].String() + return t.NodeIDs[i] < t.NodeIDs[j] }) return t, nil } func (c *Cluster) considerTopology() error { - - c.ID = c.Topology.ClusterID - // Create ClusterID if one does not already exist. if c.ID == "" { u := uuid.NewV4() @@ -1521,17 +1583,17 @@ func (c *Cluster) considerTopology() error { } // If there is no .topology file, it's safe to proceed. - if len(c.Topology.NodeSet) == 0 { + if len(c.Topology.NodeIDs) == 0 { return nil } // The local node (coordinator) must be in the .topology. - if !c.Topology.ContainsURI(c.Coordinator) { - return fmt.Errorf("coordinator %s is not in topology: %v", c.Coordinator, c.Topology.NodeSet) + if !c.Topology.ContainsID(c.Node.ID) { + return fmt.Errorf("coordinator %s is not in topology: %v", c.Node.ID, c.Topology.NodeIDs) } // If local node is the only thing in .topology, continue. - //if len(c.Topology.NodeSet) == 1 { + //if len(c.Topology.NodeIDs) == 1 { // return nil //} @@ -1543,7 +1605,7 @@ func (c *Cluster) considerTopology() error { // ReceiveEvent represents an implementation of EventHandler. func (c *Cluster) ReceiveEvent(e *NodeEvent) error { // Ignore events sent from this node. - if e.URI == c.URI { + if e.Node.ID == c.Node.ID { return nil } @@ -1554,7 +1616,7 @@ func (c *Cluster) ReceiveEvent(e *NodeEvent) error { if !c.IsCoordinator() { return nil } - return c.nodeJoin(e.URI) + return c.nodeJoin(e.Node) case NodeLeave: // Automatic nodeLeave is intentionally not implemented. case NodeUpdate: @@ -1564,16 +1626,16 @@ func (c *Cluster) ReceiveEvent(e *NodeEvent) error { return nil } -func (c *Cluster) nodeJoin(uri URI) error { +func (c *Cluster) nodeJoin(node *Node) error { if c.needTopologyAgreement() { // A host that is not part of the topology can't be added to the STARTING cluster. - if !c.Topology.ContainsURI(uri) { - err := fmt.Sprintf("host is not in topology: %v", uri) + if !c.Topology.ContainsID(node.ID) { + err := fmt.Sprintf("host is not in topology: %s", node.ID) c.logger().Print(err) return errors.New(err) } - if err := c.AddNode(uri); err != nil { + if err := c.AddNode(node); err != nil { return err } @@ -1594,20 +1656,20 @@ func (c *Cluster) nodeJoin(uri URI) error { } else { // Send the status to the remote node. This lets the remote node // know that it can proceed with opening its Holder. - return c.sendTo(uri, c.Status()) + return c.sendTo(node, c.Status()) } return nil } // Don't do anything else if the cluster already contains the node. - if c.NodeByURI(uri) != nil { + if c.nodeByID(node.ID) != nil { return nil } // If the holder does not yet contain data, go ahead and add the node. if !c.Holder.HasData() { - if err := c.AddNode(uri); err != nil { + if err := c.AddNode(node); err != nil { return err } return c.setStateAndBroadcast(ClusterStateNormal) @@ -1618,34 +1680,37 @@ func (c *Cluster) nodeJoin(uri URI) error { if err := c.setStateAndBroadcast(ClusterStateResizing); err != nil { return err } - c.joiningLeavingNodes <- nodeAction{uri, ResizeJobActionAdd} + c.joiningLeavingNodes <- nodeAction{node, ResizeJobActionAdd} return nil } // NodeLeave initiates the removal of a node from the cluster. -func (c *Cluster) NodeLeave(uri URI) error { +func (c *Cluster) NodeLeave(node *Node) error { // Refuse the request if this is not the coordinator. if !c.IsCoordinator() { - return fmt.Errorf("Node removal requests are only valid on the Coordinator node: %s", c.Coordinator) + return fmt.Errorf("Node removal requests are only valid on the Coordinator node: %s", c.CoordinatorNode().ID) } if c.State() != ClusterStateNormal { return fmt.Errorf("Cluster must be in state %s to remove a node. Current state: %s", ClusterStateNormal, c.State) } - return c.nodeLeave(uri) + return c.nodeLeave(node) } -func (c *Cluster) nodeLeave(uri URI) error { +func (c *Cluster) nodeLeave(node *Node) error { + // Get the actual node in the local cluster. + n := c.nodeByID(node.ID) + // Don't do anything else if the cluster doesn't contain the node. - if c.NodeByURI(uri) == nil { + if n == nil { return nil } // If the holder does not yet contain data, go ahead and remove the node. if !c.Holder.HasData() { - if err := c.RemoveNode(uri); err != nil { + if err := c.RemoveNode(n); err != nil { return err } return c.setStateAndBroadcast(ClusterStateNormal) @@ -1656,7 +1721,7 @@ func (c *Cluster) nodeLeave(uri URI) error { if err := c.setStateAndBroadcast(ClusterStateResizing); err != nil { return err } - c.joiningLeavingNodes <- nodeAction{uri, ResizeJobActionRemove} + c.joiningLeavingNodes <- nodeAction{n, ResizeJobActionRemove} return nil } @@ -1671,26 +1736,32 @@ func (c *Cluster) MergeClusterStatus(cs *internal.ClusterStatus) error { // Set ClusterID. c.setID(cs.ClusterID) - officialURIs := decodeURIs(cs.NodeSet) + officialNodes := DecodeNodes(cs.Nodes) // Add all nodes from the coordinator. - for _, uri := range officialURIs { - if err := c.AddNode(uri); err != nil { + for _, node := range officialNodes { + if err := c.AddNode(node); err != nil { return err } } // Remove any nodes not specified by the coordinator - // except for self. - for _, uri := range c.NodeSet() { + // except for self. Generate a list to remove first + // so that nodes aren't removed mid-loop. + nodeIDsToRemove := []string{} + for _, node := range c.Nodes { // Don't remove this node. - if uri == c.URI { + if node.ID == c.Node.ID { continue } - if NodeSet(officialURIs).ContainsURI(uri) { + if Nodes(officialNodes).ContainsID(node.ID) { continue } - if err := c.RemoveNode(uri); err != nil { + nodeIDsToRemove = append(nodeIDsToRemove, node.ID) + } + + for _, nodeID := range nodeIDsToRemove { + if err := c.RemoveNode(c.nodeByID(nodeID)); err != nil { return err } } diff --git a/cluster_internal_test.go b/cluster_internal_test.go index 75eb86f85..6c2c98e40 100644 --- a/cluster_internal_test.go +++ b/cluster_internal_test.go @@ -34,9 +34,12 @@ func TestFragCombos(t *testing.T) { t.Fatal(err) } + node0 := &Node{ID: "node0", URI: *uri0} + node1 := &Node{ID: "node1", URI: *uri1} + c := NewCluster() - c.addNodeBasicSorted(*uri0) - c.addNodeBasicSorted(*uri1) + c.addNodeBasicSorted(node0) + c.addNodeBasicSorted(node1) tests := []struct { idx string @@ -49,8 +52,8 @@ func TestFragCombos(t *testing.T) { maxSlice: uint64(2), frameViews: viewsByFrame{"f": []string{"v1", "v2"}}, expected: fragsByHost{ - URI{"http", "host0", 10101}: []frag{{"f", "v1", uint64(0)}, {"f", "v2", uint64(0)}}, - URI{"http", "host1", 10101}: []frag{{"f", "v1", uint64(1)}, {"f", "v2", uint64(1)}, {"f", "v1", uint64(2)}, {"f", "v2", uint64(2)}}, + "node0": []frag{{"f", "v1", uint64(0)}, {"f", "v2", uint64(0)}}, + "node1": []frag{{"f", "v1", uint64(1)}, {"f", "v2", uint64(1)}, {"f", "v1", uint64(2)}, {"f", "v2", uint64(2)}}, }, }, { @@ -58,8 +61,8 @@ func TestFragCombos(t *testing.T) { maxSlice: uint64(3), frameViews: viewsByFrame{"f": []string{"v0"}}, expected: fragsByHost{ - URI{"http", "host0", 10101}: []frag{{"f", "v0", uint64(1)}, {"f", "v0", uint64(2)}}, - URI{"http", "host1", 10101}: []frag{{"f", "v0", uint64(0)}, {"f", "v0", uint64(3)}}, + "node0": []frag{{"f", "v0", uint64(1)}, {"f", "v0", uint64(2)}}, + "node1": []frag{{"f", "v0", uint64(0)}, {"f", "v0", uint64(3)}}, }, }, } @@ -106,34 +109,39 @@ func TestFragSources(t *testing.T) { t.Fatal(err) } + node0 := &Node{ID: "node0", URI: *uri0} + node1 := &Node{ID: "node1", URI: *uri1} + node2 := &Node{ID: "node2", URI: *uri2} + node3 := &Node{ID: "node3", URI: *uri3} + c1 := NewCluster() c1.ReplicaN = 1 - c1.addNodeBasicSorted(*uri0) - c1.addNodeBasicSorted(*uri1) + c1.addNodeBasicSorted(node0) + c1.addNodeBasicSorted(node1) c2 := NewCluster() c2.ReplicaN = 1 - c2.addNodeBasicSorted(*uri0) - c2.addNodeBasicSorted(*uri1) - c2.addNodeBasicSorted(*uri2) + c2.addNodeBasicSorted(node0) + c2.addNodeBasicSorted(node1) + c2.addNodeBasicSorted(node2) c3 := NewCluster() c3.ReplicaN = 2 - c3.addNodeBasicSorted(*uri0) - c3.addNodeBasicSorted(*uri1) + c3.addNodeBasicSorted(node0) + c3.addNodeBasicSorted(node1) c4 := NewCluster() c4.ReplicaN = 2 - c4.addNodeBasicSorted(*uri0) - c4.addNodeBasicSorted(*uri1) - c4.addNodeBasicSorted(*uri2) + c4.addNodeBasicSorted(node0) + c4.addNodeBasicSorted(node1) + c4.addNodeBasicSorted(node2) c5 := NewCluster() c5.ReplicaN = 2 - c5.addNodeBasicSorted(*uri0) - c5.addNodeBasicSorted(*uri1) - c5.addNodeBasicSorted(*uri2) - c5.addNodeBasicSorted(*uri3) + c5.addNodeBasicSorted(node0) + c5.addNodeBasicSorted(node1) + c5.addNodeBasicSorted(node2) + c5.addNodeBasicSorted(node3) idx := newIndexWithTempPath("i") frame, err := idx.CreateFrameIfNotExists("f", FrameOptions{}) @@ -161,19 +169,19 @@ func TestFragSources(t *testing.T) { from *Cluster to *Cluster idx *Index - expected map[URI][]*internal.ResizeSource + expected map[string][]*internal.ResizeSource err string }{ { from: c1, to: c2, idx: idx, - expected: map[URI][]*internal.ResizeSource{ - URI{"http", "host0", 10101}: []*internal.ResizeSource{}, - URI{"http", "host1", 10101}: []*internal.ResizeSource{}, - URI{"http", "host2", 10101}: []*internal.ResizeSource{ - {&internal.URI{"http", "host0", 10101}, "i", "f", "standard", uint64(0)}, - {&internal.URI{"http", "host1", 10101}, "i", "f", "standard", uint64(2)}, + expected: map[string][]*internal.ResizeSource{ + "node0": []*internal.ResizeSource{}, + "node1": []*internal.ResizeSource{}, + "node2": []*internal.ResizeSource{ + {&internal.Node{"node0", &internal.URI{"http", "host0", 10101}}, "i", "f", "standard", uint64(0)}, + {&internal.Node{"node1", &internal.URI{"http", "host1", 10101}}, "i", "f", "standard", uint64(2)}, }, }, err: "", @@ -182,13 +190,13 @@ func TestFragSources(t *testing.T) { from: c4, to: c3, idx: idx, - expected: map[URI][]*internal.ResizeSource{ - URI{"http", "host0", 10101}: []*internal.ResizeSource{ - {&internal.URI{"http", "host1", 10101}, "i", "f", "standard", uint64(1)}, + expected: map[string][]*internal.ResizeSource{ + "node0": []*internal.ResizeSource{ + {&internal.Node{"node1", &internal.URI{"http", "host1", 10101}}, "i", "f", "standard", uint64(1)}, }, - URI{"http", "host1", 10101}: []*internal.ResizeSource{ - {&internal.URI{"http", "host0", 10101}, "i", "f", "standard", uint64(0)}, - {&internal.URI{"http", "host0", 10101}, "i", "f", "standard", uint64(2)}, + "node1": []*internal.ResizeSource{ + {&internal.Node{"node0", &internal.URI{"http", "host0", 10101}}, "i", "f", "standard", uint64(0)}, + {&internal.Node{"node0", &internal.URI{"http", "host0", 10101}}, "i", "f", "standard", uint64(2)}, }, }, err: "", @@ -197,15 +205,15 @@ func TestFragSources(t *testing.T) { from: c5, to: c4, idx: idx, - expected: map[URI][]*internal.ResizeSource{ - URI{"http", "host0", 10101}: []*internal.ResizeSource{ - {&internal.URI{"http", "host2", 10101}, "i", "f", "standard", uint64(0)}, - {&internal.URI{"http", "host2", 10101}, "i", "f", "standard", uint64(2)}, + expected: map[string][]*internal.ResizeSource{ + "node0": []*internal.ResizeSource{ + {&internal.Node{"node2", &internal.URI{"http", "host2", 10101}}, "i", "f", "standard", uint64(0)}, + {&internal.Node{"node2", &internal.URI{"http", "host2", 10101}}, "i", "f", "standard", uint64(2)}, }, - URI{"http", "host1", 10101}: []*internal.ResizeSource{ - {&internal.URI{"http", "host0", 10101}, "i", "f", "standard", uint64(3)}, + "node1": []*internal.ResizeSource{ + {&internal.Node{"node0", &internal.URI{"http", "host0", 10101}}, "i", "f", "standard", uint64(3)}, }, - URI{"http", "host2", 10101}: []*internal.ResizeSource{}, + "node2": []*internal.ResizeSource{}, }, err: "", }, @@ -265,33 +273,37 @@ func TestResizeJob(t *testing.T) { t.Fatal(err) } + node0 := &Node{ID: "node0", URI: *uri0} + node1 := &Node{ID: "node1", URI: *uri1} + node2 := &Node{ID: "node2", URI: *uri2} + tests := []struct { - existingURIs []URI - uri URI - action string - expectedURIs map[URI]bool + existingNodes []*Node + node *Node + action string + expectedIDs map[string]bool }{ { - existingURIs: []URI{*uri0, *uri1}, - uri: *uri2, - action: ResizeJobActionAdd, - expectedURIs: map[URI]bool{*uri0: false, *uri1: false, *uri2: false}, + existingNodes: []*Node{node0, node1}, + node: node2, + action: ResizeJobActionAdd, + expectedIDs: map[string]bool{node0.ID: false, node1.ID: false, node2.ID: false}, }, { - existingURIs: []URI{*uri0, *uri1, *uri2}, - uri: *uri2, - action: ResizeJobActionRemove, - expectedURIs: map[URI]bool{*uri0: false, *uri1: false}, + existingNodes: []*Node{node0, node1, node2}, + node: node2, + action: ResizeJobActionRemove, + expectedIDs: map[string]bool{node0.ID: false, node1.ID: false}, }, } for _, test := range tests { - actual := NewResizeJob(test.existingURIs, test.uri, test.action) + actual := NewResizeJob(test.existingNodes, test.node, test.action) if err != nil { t.Fatal(err) } - if !reflect.DeepEqual(actual.URIs, test.expectedURIs) { - t.Errorf("expected: %v, but got: %v", test.expectedURIs, actual.URIs) + if !reflect.DeepEqual(actual.IDs, test.expectedIDs) { + t.Errorf("expected: %v, but got: %v", test.expectedIDs, actual.IDs) } } } diff --git a/cluster_test.go b/cluster_test.go index b1b62c815..9bcacac9a 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -106,7 +106,7 @@ func TestCluster_OwnsSlices(t *testing.T) { func TestCluster_ContainsSlices(t *testing.T) { c := test.NewCluster(5) c.ReplicaN = 3 - slices := c.ContainsSlices("test", 10, test.NewURIFromHostPort("host2", 0)) + slices := c.ContainsSlices("test", 10, c.Nodes[2]) if !reflect.DeepEqual(slices, []uint64{0, 2, 3, 5, 6, 9, 10}) { t.Fatalf("unexpected slices for node's index: %v", slices) @@ -119,15 +119,16 @@ func TestCluster_Nodes(t *testing.T) { uri2 := test.NewURIFromHostPort("node2", 0) uri3 := test.NewURIFromHostPort("node3", 0) - nodes := []*pilosa.Node{ - {URI: uri0}, - {URI: uri1}, - {URI: uri2}, - } + node0 := &pilosa.Node{ID: "node0", URI: uri0} + node1 := &pilosa.Node{ID: "node1", URI: uri1} + node2 := &pilosa.Node{ID: "node2", URI: uri2} + node3 := &pilosa.Node{ID: "node3", URI: uri3} - t.Run("NodeSet", func(t *testing.T) { - actual := pilosa.Nodes(nodes).URIs() - expected := []pilosa.URI{uri0, uri1, uri2} + nodes := []*pilosa.Node{node0, node1, node2} + + t.Run("NodeIDs", func(t *testing.T) { + actual := pilosa.Nodes(nodes).IDs() + expected := []string{node0.ID, node1.ID, node2.ID} if !reflect.DeepEqual(actual, expected) { t.Errorf("expected: %v, but got: %v", expected, actual) } @@ -150,19 +151,8 @@ func TestCluster_Nodes(t *testing.T) { }) t.Run("Contains", func(t *testing.T) { - actualTrue := pilosa.Nodes(nodes).Contains(nodes[1]) - actualFalse := pilosa.Nodes(nodes).Contains(&pilosa.Node{}) - if !reflect.DeepEqual(actualTrue, true) { - t.Errorf("expected: %v, but got: %v", true, actualTrue) - } - if !reflect.DeepEqual(actualFalse, false) { - t.Errorf("expected: %v, but got: %v", false, actualTrue) - } - }) - - t.Run("ContainsURI", func(t *testing.T) { - actualTrue := pilosa.Nodes(nodes).ContainsURI(uri1) - actualFalse := pilosa.Nodes(nodes).ContainsURI(uri3) + actualTrue := pilosa.Nodes(nodes).Contains(node1) + actualFalse := pilosa.Nodes(nodes).Contains(node3) if !reflect.DeepEqual(actualTrue, true) { t.Errorf("expected: %v, but got: %v", true, actualTrue) } @@ -185,58 +175,66 @@ func TestCluster_Coordinator(t *testing.T) { uri1 := test.NewURIFromHostPort("node1", 0) uri2 := test.NewURIFromHostPort("node2", 0) + node1 := &pilosa.Node{ID: "node1", URI: uri1} + node2 := &pilosa.Node{ID: "node2", URI: uri2} + c1 := *pilosa.NewCluster() - c1.URI = uri1 - c1.Coordinator = uri1 + c1.Node = node1 + c1.Coordinator = node1.URI c2 := *pilosa.NewCluster() - c2.URI = uri2 - c2.Coordinator = uri1 + c2.Node = node2 + c2.Coordinator = node1.URI t.Run("IsCoordinator", func(t *testing.T) { if !c1.IsCoordinator() { - t.Errorf("!IsCoordinator error: %v", c1.URI) + t.Errorf("!IsCoordinator error: %v", c1.Node) } else if c2.IsCoordinator() { - t.Errorf("IsCoordinator error: %v", c2.URI) + t.Errorf("IsCoordinator error: %v", c2.Node) } }) } func TestCluster_Topology(t *testing.T) { - c1 := test.NewCluster(1) + c1 := test.NewCluster(1) // automatically creates Node{ID: "node0"} - uri1 := test.NewURIFromHostPort("node1", 0) - uri2 := test.NewURIFromHostPort("node2", 0) - base := test.NewURIFromHostPort("host0", 0) + uri0 := test.NewURIFromHostPort("host0", 0) + uri1 := test.NewURIFromHostPort("host1", 0) + uri2 := test.NewURIFromHostPort("host2", 0) invalid := test.NewURIFromHostPort("invalid", 0) + node0 := &pilosa.Node{ID: "node0", URI: uri0} + node1 := &pilosa.Node{ID: "node1", URI: uri1} + node2 := &pilosa.Node{ID: "node2", URI: uri2} + nodeinvalid := &pilosa.Node{ID: "nodeinvalid", URI: invalid} + t.Run("AddNode", func(t *testing.T) { - err := c1.AddNode(uri1) + err := c1.AddNode(node1) if err != nil { t.Fatal(err) } // add the same host. - err = c1.AddNode(uri1) + err = c1.AddNode(node1) if err != nil { t.Fatal(err) } - err = c1.AddNode(uri2) + err = c1.AddNode(node2) if err != nil { t.Fatal(err) } - actual := c1.NodeSet() - expected := []pilosa.URI{base, uri1, uri2} + actual := c1.NodeIDs() + expected := []string{node0.ID, node1.ID, node2.ID} if !reflect.DeepEqual(actual, expected) { t.Errorf("expected: %v, but got: %v", expected, actual) } }) - t.Run("ContainsURI", func(t *testing.T) { - if !c1.Topology.ContainsURI(uri1) { - t.Errorf("!ContainsHost error: %v", uri1) - } else if c1.Topology.ContainsURI(invalid) { - t.Errorf("ContainsHost error: %v", invalid) + t.Run("ContainsID", func(t *testing.T) { + if !c1.Topology.ContainsID(node1.ID) { + t.Errorf("!ContainsHost error: %v", node1.ID) + } else if c1.Topology.ContainsID(nodeinvalid.ID) { + t.Errorf("ContainsHost error: %v", nodeinvalid.ID) } }) } @@ -260,12 +258,12 @@ func TestCluster_ResizeStates(t *testing.T) { } expectedTop := &pilosa.Topology{ - NodeSet: []pilosa.URI{node.URI}, + NodeIDs: []string{node.Node.ID}, } // Verify topology file. - if !reflect.DeepEqual(node.Topology.NodeSet, expectedTop.NodeSet) { - t.Errorf("expected topology: %v, but got: %v", expectedTop.NodeSet, node.Topology.NodeSet) + if !reflect.DeepEqual(node.Topology.NodeIDs, expectedTop.NodeIDs) { + t.Errorf("expected topology: %v, but got: %v", expectedTop.NodeIDs, node.Topology.NodeIDs) } // Close TestCluster. @@ -282,7 +280,7 @@ func TestCluster_ResizeStates(t *testing.T) { // write topology to data file top := &pilosa.Topology{ - NodeSet: []pilosa.URI{node.URI}, + NodeIDs: []string{node.Node.ID}, } tc.WriteTopology(node.Path, top) @@ -310,14 +308,12 @@ func TestCluster_ResizeStates(t *testing.T) { // write topology to data file top := &pilosa.Topology{ - NodeSet: []pilosa.URI{ - test.NewURIFromHostPort("some-other-host", 0), - }, + NodeIDs: []string{"some-other-host"}, } tc.WriteTopology(node.Path, top) // Open TestCluster. - expected := "considerTopology: coordinator http://host0:0 is not in topology: [http://some-other-host:0]" + expected := "considerTopology: coordinator node0 is not in topology: [some-other-host]" err := tc.Open() if err == nil || err.Error() != expected { t.Errorf("did not receive expected error: %s", expected) @@ -351,14 +347,14 @@ func TestCluster_ResizeStates(t *testing.T) { } expectedTop := &pilosa.Topology{ - NodeSet: []pilosa.URI{node0.URI, node1.URI}, + NodeIDs: []string{node0.Node.ID, node1.Node.ID}, } // Verify topology file. - if !reflect.DeepEqual(node0.Topology.NodeSet, expectedTop.NodeSet) { - t.Errorf("expected node0 topology: %v, but got: %v", expectedTop.NodeSet, node0.Topology.NodeSet) - } else if !reflect.DeepEqual(node1.Topology.NodeSet, expectedTop.NodeSet) { - t.Errorf("expected node1 topology: %v, but got: %v", expectedTop.NodeSet, node1.Topology.NodeSet) + if !reflect.DeepEqual(node0.Topology.NodeIDs, expectedTop.NodeIDs) { + t.Errorf("expected node0 topology: %v, but got: %v", expectedTop.NodeIDs, node0.Topology.NodeIDs) + } else if !reflect.DeepEqual(node1.Topology.NodeIDs, expectedTop.NodeIDs) { + t.Errorf("expected node1 topology: %v, but got: %v", expectedTop.NodeIDs, node1.Topology.NodeIDs) } // Close TestCluster. @@ -372,13 +368,9 @@ func TestCluster_ResizeStates(t *testing.T) { tc.AddNode(false) node0 := tc.Clusters[0] - u0 := test.NewURIFromHostPort("host0", 0) - //u1 := test.NewURIFromHostPort("host1", 0) - u2 := test.NewURIFromHostPort("host2", 0) - // write topology to data file top := &pilosa.Topology{ - NodeSet: []pilosa.URI{u0, u2}, + NodeIDs: []string{"node0", "node2"}, } tc.WriteTopology(node0.Path, top) @@ -393,7 +385,7 @@ func TestCluster_ResizeStates(t *testing.T) { } // Expect an error by adding a node not in the topology. - expectedError := "host is not in topology: http://host1:0" + expectedError := "host is not in topology: node1" err := tc.AddNode(false) if err == nil || err.Error() != expectedError { t.Errorf("did not receive expected error: %s", expectedError) @@ -477,14 +469,14 @@ func TestCluster_ResizeStates(t *testing.T) { } expectedTop := &pilosa.Topology{ - NodeSet: []pilosa.URI{node0.URI, node1.URI}, + NodeIDs: []string{node0.Node.ID, node1.Node.ID}, } // Verify topology file. - if !reflect.DeepEqual(node0.Topology.NodeSet, expectedTop.NodeSet) { - t.Errorf("expected node0 topology: %v, but got: %v", expectedTop.NodeSet, node0.Topology.NodeSet) - } else if !reflect.DeepEqual(node1.Topology.NodeSet, expectedTop.NodeSet) { - t.Errorf("expected node1 topology: %v, but got: %v", expectedTop.NodeSet, node1.Topology.NodeSet) + if !reflect.DeepEqual(node0.Topology.NodeIDs, expectedTop.NodeIDs) { + t.Errorf("expected node0 topology: %v, but got: %v", expectedTop.NodeIDs, node0.Topology.NodeIDs) + } else if !reflect.DeepEqual(node1.Topology.NodeIDs, expectedTop.NodeIDs) { + t.Errorf("expected node1 topology: %v, but got: %v", expectedTop.NodeIDs, node1.Topology.NodeIDs) } // Bits @@ -519,28 +511,23 @@ func TestCluster_ResizeStates(t *testing.T) { // Ensures that coordinator can be changed. func TestCluster_SetCoordinator(t *testing.T) { t.Run("SetCoordinator", func(t *testing.T) { - c := test.NewCluster(1) - oldURI, err := pilosa.NewURIFromAddress("localhost:8888") - if err != nil { - t.Fatal(err) - } - c.Coordinator = *oldURI + c := test.NewCluster(2) - newURI, err := pilosa.NewURIFromAddress("localhost:9999") - if err != nil { - t.Fatal(err) - } + oldNode := c.Nodes[0] + newNode := c.Nodes[1] // Set coordinator to the same value. - c.SetCoordinator(c.Coordinator, *oldURI) - if c.Coordinator != *oldURI { - t.Errorf("expected coordinator: %s, but got: %s", c.Coordinator, *oldURI) + if set := c.SetCoordinator(oldNode, oldNode); set { + t.Errorf("did not expect coordinator to change") + } else if c.Coordinator != oldNode.URI { + t.Errorf("expected coordinator: %s, but got: %s", c.Coordinator, oldNode.URI) } // Set coordinator to a new value. - c.SetCoordinator(c.Coordinator, *newURI) - if c.Coordinator != *newURI { - t.Errorf("expected coordinator: %s, but got: %s", c.Coordinator, *newURI) + if set := c.SetCoordinator(oldNode, newNode); !set { + t.Errorf("expected coordinator to change") + } else if c.Coordinator != newNode.URI { + t.Errorf("expected coordinator: %s, but got: %s", c.Coordinator, newNode.URI) } }) } diff --git a/ctl/backup_test.go b/ctl/backup_test.go index bb541b344..d23b1a917 100644 --- a/ctl/backup_test.go +++ b/ctl/backup_test.go @@ -50,7 +50,9 @@ func TestBackupCommand_Run(t *testing.T) { if err != nil { t.Fatal(err) } - s.Handler.URI = *uri + node := &pilosa.Node{ID: "node", URI: *uri} + + s.Handler.Node = node s.Handler.Cluster = test.NewCluster(1) s.Handler.Cluster.Nodes[0].URI = *uri s.Handler.Holder = hldr.Holder diff --git a/ctl/export_test.go b/ctl/export_test.go index 9e4381d39..5d1d5a4d7 100644 --- a/ctl/export_test.go +++ b/ctl/export_test.go @@ -63,9 +63,11 @@ func TestExportCommand_Run(t *testing.T) { if err != nil { t.Fatal(err) } - s.Handler.URI = *uri + node := &pilosa.Node{ID: "node", URI: *uri} + + s.Handler.Node = node s.Handler.Cluster = test.NewCluster(1) - s.Handler.Cluster.Nodes[0].URI = *uri + s.Handler.Cluster.Nodes[0] = node s.Handler.Holder = hldr.Holder cm.Host = s.Host() diff --git a/ctl/import_test.go b/ctl/import_test.go index af38292cd..dcf341187 100644 --- a/ctl/import_test.go +++ b/ctl/import_test.go @@ -69,9 +69,11 @@ func TestImportCommand_Run(t *testing.T) { if err != nil { t.Fatal(err) } - s.Handler.URI = *uri + node := &pilosa.Node{ID: "node", URI: *uri} + + s.Handler.Node = node s.Handler.Cluster = test.NewCluster(1) - s.Handler.Cluster.Nodes[0].URI = *uri + s.Handler.Cluster.Nodes[0] = node s.Handler.Holder = hldr.Holder cm.Host = s.Host() @@ -109,9 +111,11 @@ func TestImportCommand_RunValue(t *testing.T) { if err != nil { t.Fatal(err) } - s.Handler.URI = *uri + node := &pilosa.Node{ID: "node", URI: *uri} + + s.Handler.Node = node s.Handler.Cluster = test.NewCluster(1) - s.Handler.Cluster.Nodes[0].URI = *uri + s.Handler.Cluster.Nodes[0] = node s.Handler.Holder = hldr.Holder cm.Host = s.Host() diff --git a/ctl/restore_test.go b/ctl/restore_test.go index 60a0be9f6..bb8eb3b5f 100644 --- a/ctl/restore_test.go +++ b/ctl/restore_test.go @@ -52,7 +52,9 @@ func TestRestoreCommand_Run(t *testing.T) { if err != nil { t.Fatal(err) } - s.Handler.URI = *uri + node := &pilosa.Node{ID: "node", URI: *uri} + + s.Handler.Node = node s.Handler.Cluster = test.NewCluster(1) s.Handler.Cluster.Nodes[0].URI = *uri s.Handler.Holder = hldr.Holder diff --git a/event.go b/event.go index 0b7485f76..5df69361b 100644 --- a/event.go +++ b/event.go @@ -27,7 +27,7 @@ const ( // NodeEvent is a single event related to node activity in the cluster. type NodeEvent struct { Event NodeEventType - URI URI + Node *Node } // EventHandler is the interface for the pilosa object which knows how to diff --git a/executor.go b/executor.go index 3460d04df..bd8d63ae2 100644 --- a/executor.go +++ b/executor.go @@ -40,7 +40,7 @@ type Executor struct { Holder *Holder // Local hostname & cluster configuration. - URI URI + Node *Node Cluster *Cluster // Client used for remote requests. @@ -956,7 +956,7 @@ func (e *Executor) executeClearBitView(ctx context.Context, index string, c *pql ret := false for _, node := range e.Cluster.FragmentNodes(index, slice) { // Update locally if host matches. - if node.URI == e.URI { + if node.ID == e.Node.ID { val, err := f.ClearBit(view, rowID, colID, nil) if err != nil { return false, err @@ -1061,7 +1061,7 @@ func (e *Executor) executeSetBitView(ctx context.Context, index string, c *pql.C for _, node := range e.Cluster.FragmentNodes(index, slice) { // Update locally if host matches. - if node.URI == e.URI { + if node.ID == e.Node.ID { val, err := f.SetBit(view, rowID, colID, timestamp) if err != nil { return false, err @@ -1140,7 +1140,7 @@ func (e *Executor) executeSetFieldValue(ctx context.Context, index string, c *pq } // Execute on remote nodes in parallel. - nodes := Nodes(e.Cluster.Nodes).FilterURI(e.URI) + nodes := Nodes(e.Cluster.Nodes).FilterID(e.Node.ID) resp := make(chan error, len(nodes)) for _, node := range nodes { go func(node *Node) { @@ -1198,7 +1198,7 @@ func (e *Executor) executeSetRowAttrs(ctx context.Context, index string, c *pql. } // Execute on remote nodes in parallel. - nodes := Nodes(e.Cluster.Nodes).FilterURI(e.URI) + nodes := Nodes(e.Cluster.Nodes).FilterID(e.Node.ID) resp := make(chan error, len(nodes)) for _, node := range nodes { go func(node *Node) { @@ -1285,7 +1285,7 @@ func (e *Executor) executeBulkSetRowAttrs(ctx context.Context, index string, cal } // Execute on remote nodes in parallel. - nodes := Nodes(e.Cluster.Nodes).FilterURI(e.URI) + nodes := Nodes(e.Cluster.Nodes).FilterID(e.Node.ID) resp := make(chan error, len(nodes)) for _, node := range nodes { go func(node *Node) { @@ -1344,7 +1344,7 @@ func (e *Executor) executeSetColumnAttrs(ctx context.Context, index string, c *p } // Execute on remote nodes in parallel. - nodes := Nodes(e.Cluster.Nodes).FilterURI(e.URI) + nodes := Nodes(e.Cluster.Nodes).FilterID(e.Node.ID) resp := make(chan error, len(nodes)) for _, node := range nodes { go func(node *Node) { @@ -1451,7 +1451,7 @@ func (e *Executor) mapReduce(ctx context.Context, index string, slices []uint64, if !opt.Remote { nodes = Nodes(e.Cluster.Nodes).Clone() } else { - nodes = []*Node{e.Cluster.NodeByURI(e.URI)} + nodes = []*Node{e.Cluster.nodeByID(e.Node.ID)} } // Start mapping across all primary owners. @@ -1507,7 +1507,7 @@ func (e *Executor) mapper(ctx context.Context, ch chan mapResponse, nodes []*Nod resp := mapResponse{node: n, slices: nodeSlices} // Send local slices to mapper, otherwise remote exec. - if n.URI == e.URI { + if n.ID == e.Node.ID { resp.result, resp.err = e.mapperLocal(ctx, nodeSlices, mapFn, reduceFn) } else if !opt.Remote { results, err := e.remoteExec(ctx, n, index, &pql.Query{Calls: []*pql.Call{c}}, nodeSlices, opt) diff --git a/fragment.go b/fragment.go index 3df788629..3b09b925e 100644 --- a/fragment.go +++ b/fragment.go @@ -1685,7 +1685,7 @@ func (h *blockHasher) WriteValue(v uint64) { type FragmentSyncer struct { Fragment *Fragment - URI URI + Node *Node Cluster *Cluster RemoteClient *http.Client @@ -1715,7 +1715,7 @@ func (s *FragmentSyncer) SyncFragment() error { blockSets := make([][]FragmentBlock, 0, len(nodes)) for _, node := range nodes { // Read local blocks. - if node.URI == s.URI { + if node.ID == s.Node.ID { b := s.Fragment.Blocks() blockSets = append(blockSets, b) continue @@ -1789,7 +1789,7 @@ func (s *FragmentSyncer) syncBlock(id int) error { var pairSets []PairSet var clients []InternalClient for _, node := range s.Cluster.FragmentNodes(f.Index(), f.Slice()) { - if s.URI == node.URI { + if s.Node.ID == node.ID { continue } diff --git a/gossip/gossip.go b/gossip/gossip.go index 243d19738..d0868be92 100644 --- a/gossip/gossip.go +++ b/gossip/gossip.go @@ -43,6 +43,7 @@ var _ memberlist.Delegate = &GossipMemberSet{} // GossipMemberSet represents a gossip implementation of MemberSet using memberlist. type GossipMemberSet struct { mu sync.RWMutex + node *pilosa.Node memberlist *memberlist.Memberlist handler pilosa.BroadcastHandler @@ -55,20 +56,6 @@ type GossipMemberSet struct { LogOutput io.Writer } -// Nodes implements the MemberSet interface and returns a list of nodes in the cluster. -func (g *GossipMemberSet) Nodes() []*pilosa.Node { - g.mu.RLock() - defer g.mu.RUnlock() - - a := make([]*pilosa.Node, 0, g.memberlist.NumMembers()) - for _, n := range g.memberlist.Members() { - uri, _ := pilosa.NewURIFromAddress(n.Name) - // TODO don't swallow the error above - a = append(a, &pilosa.Node{URI: *uri}) - } - return a -} - // Start implements the BroadcastReceiver interface and sets the BroadcastHandler. func (g *GossipMemberSet) Start(h pilosa.BroadcastHandler) error { g.handler = h @@ -81,11 +68,13 @@ func (g *GossipMemberSet) Seed() string { } // Open implements the MemberSet interface to start network activity. -func (g *GossipMemberSet) Open() error { +func (g *GossipMemberSet) Open(n *pilosa.Node) error { if g.handler == nil { return fmt.Errorf("must call Start(pilosa.BroadcastHandler) before calling Open()") } + g.node = n + err := error(nil) g.mu.Lock() g.memberlist, err = memberlist.Create(g.config.memberlistConfig) @@ -112,7 +101,7 @@ func (g *GossipMemberSet) Open() error { nodes := []*pilosa.Node{&pilosa.Node{URI: *uri}} //TODO: support a list of seeds g.mu.RLock() - err = g.joinWithRetry(pilosa.NodeSet(pilosa.Nodes(nodes).URIs()).ToHostPortStrings()) + err = g.joinWithRetry(pilosa.URIs(pilosa.Nodes(nodes).URIs()).HostPortStrings()) g.mu.RUnlock() if err != nil { return errors.Wrap(err, "joinWithRetry") @@ -280,7 +269,12 @@ func (g *GossipMemberSet) SendAsync(pb proto.Message) error { // NodeMeta implementation of the memberlist.Delegate interface. func (g *GossipMemberSet) NodeMeta(limit int) []byte { - return []byte{} + buf, err := proto.Marshal(pilosa.EncodeNode(g.node)) + if err != nil { + g.logger().Printf("marshal message error: %s", err) + return []byte{} + } + return buf } // NotifyMsg implementation of the memberlist.Delegate interface @@ -387,14 +381,19 @@ func (g *GossipEventReceiver) listen() { continue } - uri, _ := pilosa.NewURIFromAddress(e.Node.Name) - // TODO: don't swallow this error + // Get the node from the event.Node meta data. + var n internal.Node + if err := proto.Unmarshal(e.Node.Meta, &n); err != nil { + // TODO: consider logging error + continue + } + node := pilosa.DecodeNode(&n) ne := &pilosa.NodeEvent{ Event: nodeEventType, - URI: *uri, + Node: node, } - _ = g.eventHandler.ReceiveEvent(ne) // TODO: don't swallow this error + _ = g.eventHandler.ReceiveEvent(ne) } } diff --git a/handler.go b/handler.go index c89abc3bf..a12e7b391 100644 --- a/handler.go +++ b/handler.go @@ -57,7 +57,7 @@ type Handler struct { StatusHandler StatusHandler // Local hostname & cluster configuration. - URI URI + Node *Node Cluster *Cluster RemoteClient *http.Client @@ -268,8 +268,8 @@ func (h *Handler) handleGetStatus(w http.ResponseWriter, r *http.Request) { cs := pb.(*internal.ClusterStatus) if err := json.NewEncoder(w).Encode(getStatusResponse{ - State: cs.State, - NodeSet: decodeURIs(cs.NodeSet), + State: cs.State, + Nodes: DecodeNodes(cs.Nodes), }); err != nil { h.logger().Printf("write status response error: %s", err) } @@ -280,8 +280,8 @@ type getSchemaResponse struct { } type getStatusResponse struct { - State string `json:"state"` - NodeSet []URI `json:"nodes"` + State string `json:"state"` + Nodes []*Node `json:"nodes"` } // handlePostQuery handles /query requests. @@ -1206,8 +1206,8 @@ func (h *Handler) handlePostImport(w http.ResponseWriter, r *http.Request) { } // Validate that this handler owns the slice. - if !h.Cluster.OwnsFragment(h.URI, req.Index, req.Slice) { - msg := fmt.Sprintf("host does not own slice %s-%s slice:%d", h.URI, req.Index, req.Slice) + if !h.Cluster.OwnsFragment(h.Node.ID, req.Index, req.Slice) { + msg := fmt.Sprintf("host does not own slice %s-%s slice:%d", h.Node.ID, req.Index, req.Slice) http.Error(w, msg, http.StatusPreconditionFailed) return } @@ -1276,8 +1276,8 @@ func (h *Handler) handlePostImportValue(w http.ResponseWriter, r *http.Request) } // Validate that this handler owns the slice. - if !h.Cluster.OwnsFragment(h.URI, req.Index, req.Slice) { - msg := fmt.Sprintf("host does not own slice %s-%s slice:%d", h.URI, req.Index, req.Slice) + if !h.Cluster.OwnsFragment(h.Node.ID, req.Index, req.Slice) { + msg := fmt.Sprintf("host does not own slice %s-%s slice:%d", h.Node.ID, req.Index, req.Slice) http.Error(w, msg, http.StatusPreconditionFailed) return } @@ -1342,8 +1342,8 @@ func (h *Handler) handleGetExportCSV(w http.ResponseWriter, r *http.Request) { } // Validate that this handler owns the slice. - if !h.Cluster.OwnsFragment(h.URI, index, slice) { - msg := fmt.Sprintf("host does not own slice %s-%s slice:%d", h.URI, index, slice) + if !h.Cluster.OwnsFragment(h.Node.ID, index, slice) { + msg := fmt.Sprintf("host does not own slice %s-%s slice:%d", h.Node.ID, index, slice) http.Error(w, msg, http.StatusPreconditionFailed) return } @@ -1570,7 +1570,7 @@ func (h *Handler) handlePostFrameRestore(w http.ResponseWriter, r *http.Request) // Loop over each slice and import it if this node owns it. for slice := uint64(0); slice <= maxSlices[indexName]; slice++ { // Ignore this slice if we don't own it. - if !h.Cluster.OwnsFragment(h.URI, indexName, slice) { + if !h.Cluster.OwnsFragment(h.Node.ID, indexName, slice) { continue } @@ -1964,31 +1964,30 @@ func (h *Handler) handlePostClusterResizeSetCoordinator(w http.ResponseWriter, r return } - oldURI := h.Cluster.Coordinator + oldNode := h.Cluster.nodeByURI(h.Cluster.Coordinator) + if oldNode == nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + newNode := h.Cluster.nodeByID(req.ID) + if newNode == nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } - var newURI *URI if err := func() error { - newURI, err = NewURIFromAddress(req.Address) - if err != nil { - return fmt.Errorf("problem with set-coordinator address: %s", err) - } - - //if !Nodes(h.Cluster.Nodes).ContainsURI(*newURI) { - // return fmt.Errorf("set-coordinator node does not exist: %s", newURI) - //} - // Send the set-coordinator message to all nodes. err := h.Broadcaster.SendSync( &internal.SetCoordinatorMessage{ - Old: (&h.Cluster.Coordinator).Encode(), - New: newURI.Encode(), + Old: EncodeNode(oldNode), + New: EncodeNode(newNode), }) if err != nil { return fmt.Errorf("problem sending SetCoordinator message: %s", err) } // Set Coordinator on local node. - h.Cluster.SetCoordinator(oldURI, *newURI) + _ = h.Cluster.SetCoordinator(oldNode, newNode) return nil }(); err != nil { @@ -1998,20 +1997,20 @@ func (h *Handler) handlePostClusterResizeSetCoordinator(w http.ResponseWriter, r // Encode response. if err := json.NewEncoder(w).Encode(setCoordinatorResponse{ - Old: &oldURI, - New: newURI, + Old: oldNode, + New: newNode, }); err != nil { h.logger().Printf("response encoding error: %s", err) } } type setCoordinatorRequest struct { - Address string `json:"address"` + ID string `json:"id"` } type setCoordinatorResponse struct { - Old *URI `json:"old"` - New *URI `json:"new"` + Old *Node `json:"old"` + New *Node `json:"new"` } // handlePostClusterResizeRemoveNode handles POST /cluster/resize/remove-node request. @@ -2024,19 +2023,16 @@ func (h *Handler) handlePostClusterResizeRemoveNode(w http.ResponseWriter, r *ht return } - var removeURI *URI + removeNode := h.Cluster.nodeByID(req.ID) + if removeNode == nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } if err := func() error { - removeURI, err = NewURIFromAddress(req.Address) - if err != nil { - return fmt.Errorf("problem with remove node address: %s", err) - } - - // TODO: make sure the address is in the cluster - // TODO: prevent removing the coordinator node // Start the resize process (similar to NodeJoin) - err := h.Cluster.NodeLeave(*removeURI) + err := h.Cluster.NodeLeave(removeNode) if err != nil { return err } @@ -2049,18 +2045,18 @@ func (h *Handler) handlePostClusterResizeRemoveNode(w http.ResponseWriter, r *ht // Encode response. if err := json.NewEncoder(w).Encode(removeNodeResponse{ - Remove: removeURI, + Remove: removeNode, }); err != nil { h.logger().Printf("response encoding error: %s", err) } } type removeNodeRequest struct { - Address string `json:"address"` + ID string `json:"id"` } type removeNodeResponse struct { - Remove *URI `json:"remove"` + Remove *Node `json:"remove"` } // handlePostClusterResizeAbort handles POST /cluster/resize/abort request. @@ -2221,7 +2217,7 @@ func (h *Handler) handlePostClusterMessage(w http.ResponseWriter, r *http.Reques } func (h *Handler) handleGetID(w http.ResponseWriter, r *http.Request) { - _, err := w.Write([]byte(h.Holder.NodeID)) + _, err := w.Write([]byte(h.Cluster.Node.ID)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } diff --git a/handler_test.go b/handler_test.go index b89b7f59c..0f2b2dc00 100644 --- a/handler_test.go +++ b/handler_test.go @@ -147,7 +147,7 @@ func TestHandler_Status(t *testing.T) { h.ServeHTTP(w, test.MustNewHTTPRequest("GET", "/status", nil)) if w.Code != http.StatusOK { t.Fatalf("unexpected status code: %d", w.Code) - } else if body := w.Body.String(); body != `{"state":"NORMAL","nodes":[{"scheme":"http","host":"localhost","port":10101}]}`+"\n" { + } else if body := w.Body.String(); body != `{"state":"NORMAL","nodes":[{"id":"test-node","uri":{"scheme":"http","host":"localhost","port":10101}}]}`+"\n" { t.Fatalf("unexpected body: %s", body) } } @@ -1215,8 +1215,8 @@ func TestHandler_Fragment_Nodes(t *testing.T) { h.ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("unexpected status code: %d", w.Code) - } else if w.Body.String() != `[{"uri":{"scheme":"http","host":"host2"}},{"uri":{"scheme":"http","host":"host0"}}]`+"\n" { - t.Fatalf("unexpected body: %q", w.Body.String()) + } else if body := w.Body.String(); body != `[{"id":"node2","uri":{"scheme":"http","host":"host2"}},{"id":"node0","uri":{"scheme":"http","host":"host0"}}]`+"\n" { + t.Fatalf("unexpected body: %q", body) } } diff --git a/holder.go b/holder.go index c282e2686..4c6c10423 100644 --- a/holder.go +++ b/holder.go @@ -69,8 +69,6 @@ type Holder struct { CacheFlushInterval time.Duration LogOutput io.Writer - - NodeID string } // NewHolder returns a new instance of Holder. @@ -528,25 +526,29 @@ func (h *Holder) setFileLimit() { func (h *Holder) logger() *log.Logger { return log.New(h.LogOutput, "", log.LstdFlags) } -func (h *Holder) loadNodeID() error { +func (h *Holder) loadNodeID() (string, error) { idPath := path.Join(h.Path, "ID") nodeID := "" - nodeIDBytes, err := ioutil.ReadFile(idPath) - if err == nil { - h.NodeID = strings.TrimSpace(string(nodeIDBytes)) - } else if os.IsNotExist(err) { - u := uuid.NewV4() - nodeID = u.String() - err = ioutil.WriteFile(idPath, []byte(nodeID), 0600) - if err != nil { - return err - } - h.NodeID = nodeID - } else if err != nil { - return err + + h.logger().Printf("load NodeID: %s", idPath) + if err := os.MkdirAll(h.Path, 0777); err != nil { + return "", err } - return nil + nodeIDBytes, err := ioutil.ReadFile(idPath) + if err == nil { + nodeID = strings.TrimSpace(string(nodeIDBytes)) + } else if os.IsNotExist(err) { + nodeID = uuid.NewV4().String() + err = ioutil.WriteFile(idPath, []byte(nodeID), 0600) + if err != nil { + return "", err + } + } else if err != nil { + return "", err + } + + return nodeID, nil } // HolderSyncer is an active anti-entropy tool that compares the local holder @@ -554,7 +556,7 @@ func (h *Holder) loadNodeID() error { type HolderSyncer struct { Holder *Holder - URI URI + Node *Node Cluster *Cluster RemoteClient *http.Client @@ -610,7 +612,7 @@ func (s *HolderSyncer) SyncHolder() error { for slice := uint64(0); slice <= s.Holder.Index(di.Name).MaxSlice(); slice++ { // Ignore slices that this host doesn't own. - if !s.Cluster.OwnsFragment(s.URI, di.Name, slice) { + if !s.Cluster.OwnsFragment(s.Node.ID, di.Name, slice) { continue } @@ -652,7 +654,7 @@ func (s *HolderSyncer) syncIndex(index string) error { s.Stats.CountWithCustomTags("ColumnAttrStoreBlocks", int64(len(blks)), 1.0, []string{indexTag}) // Sync with every other host. - for _, node := range Nodes(s.Cluster.Nodes).FilterURI(s.URI) { + for _, node := range Nodes(s.Cluster.Nodes).FilterID(s.Node.ID) { client := NewInternalHTTPClientFromURI(&node.URI, s.RemoteClient) // Retrieve attributes from differing blocks. @@ -663,7 +665,7 @@ func (s *HolderSyncer) syncIndex(index string) error { } else if len(m) == 0 { continue } - s.Stats.CountWithCustomTags("ColumnAttrDiff", int64(len(m)), 1.0, []string{indexTag, node.URI.HostPort()}) + s.Stats.CountWithCustomTags("ColumnAttrDiff", int64(len(m)), 1.0, []string{indexTag, node.ID}) // Update local copy. if err := idx.ColumnAttrStore().SetBulkAttrs(m); err != nil { @@ -698,7 +700,7 @@ func (s *HolderSyncer) syncFrame(index, name string) error { s.Stats.CountWithCustomTags("RowAttrStoreBlocks", int64(len(blks)), 1.0, []string{indexTag, frameTag}) // Sync with every other host. - for _, node := range Nodes(s.Cluster.Nodes).FilterURI(s.URI) { + for _, node := range Nodes(s.Cluster.Nodes).FilterID(s.Node.ID) { client := NewInternalHTTPClientFromURI(&node.URI, s.RemoteClient) // Retrieve attributes from differing blocks. @@ -711,7 +713,7 @@ func (s *HolderSyncer) syncFrame(index, name string) error { } else if len(m) == 0 { continue } - s.Stats.CountWithCustomTags("RowAttrDiff", int64(len(m)), 1.0, []string{indexTag, frameTag, node.URI.HostPort()}) + s.Stats.CountWithCustomTags("RowAttrDiff", int64(len(m)), 1.0, []string{indexTag, frameTag, node.ID}) // Update local copy. if err := f.RowAttrStore().SetBulkAttrs(m); err != nil { @@ -751,7 +753,7 @@ func (s *HolderSyncer) syncFragment(index, frame, view string, slice uint64) err // Sync fragments together. fs := FragmentSyncer{ Fragment: frag, - URI: s.URI, + Node: s.Node, Cluster: s.Cluster, Closing: s.Closing, RemoteClient: s.RemoteClient, @@ -765,7 +767,7 @@ func (s *HolderSyncer) syncFragment(index, frame, view string, slice uint64) err // HolderCleaner removes fragments and data files that are no longer used. type HolderCleaner struct { - URI URI + Node *Node Holder *Holder Cluster *Cluster @@ -794,7 +796,7 @@ func (c *HolderCleaner) CleanHolder() error { } // Get the fragments that node is responsible for (based on hash(index, node)). - containedSlices := c.Cluster.ContainsSlices(index.Name(), index.MaxSlice(), c.URI) + containedSlices := c.Cluster.ContainsSlices(index.Name(), index.MaxSlice(), c.Node) // Get the fragments registered in memory. for _, frame := range index.Frames() { diff --git a/holder_test.go b/holder_test.go index 16f4c8abf..3422fe081 100644 --- a/holder_test.go +++ b/holder_test.go @@ -419,7 +419,7 @@ func TestHolderSyncer_SyncHolder(t *testing.T) { s.Handler.Executor.ExecuteFn = func(ctx context.Context, index string, query *pql.Query, slices []uint64, opt *pilosa.ExecOptions) ([]interface{}, error) { e := pilosa.NewExecutor(client) e.Holder = hldr1.Holder - e.URI = cluster.Nodes[1].URI + e.Node = cluster.Nodes[1] e.Cluster = cluster return e.Execute(ctx, index, query, slices, opt) } @@ -487,7 +487,7 @@ func TestHolderSyncer_SyncHolder(t *testing.T) { // Set up syncer. syncer := pilosa.HolderSyncer{ Holder: hldr0.Holder, - URI: cluster.Nodes[0].URI, + Node: cluster.Nodes[0], Cluster: cluster, RemoteClient: pilosa.GetHTTPClient(nil), Stats: pilosa.NopStatsClient, @@ -586,7 +586,7 @@ func TestHolderCleaner_CleanHolder(t *testing.T) { // Set up cleaner for replication 2. cleaner2 := pilosa.HolderCleaner{ - URI: cluster.Nodes[0].URI, + Node: cluster.Nodes[0], Holder: hldr0.Holder, Cluster: cluster, } @@ -629,7 +629,7 @@ func TestHolderCleaner_CleanHolder(t *testing.T) { // Set up cleaner for replication 1. cleaner1 := pilosa.HolderCleaner{ - URI: cluster.Nodes[0].URI, + Node: cluster.Nodes[0], Holder: hldr0.Holder, Cluster: cluster, } diff --git a/internal/private.pb.go b/internal/private.pb.go index 905f004d5..ae6247bb6 100644 --- a/internal/private.pb.go +++ b/internal/private.pb.go @@ -30,6 +30,7 @@ CreateInputDefinitionMessage DeleteInputDefinitionMessage URI + Node NodeStateMessage NodeStatus ClusterStatus @@ -673,21 +674,45 @@ func (m *URI) GetPort() uint32 { return 0 } +type Node struct { + ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` + URI *URI `protobuf:"bytes,2,opt,name=URI" json:"URI,omitempty"` +} + +func (m *Node) Reset() { *m = Node{} } +func (m *Node) String() string { return proto.CompactTextString(m) } +func (*Node) ProtoMessage() {} +func (*Node) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{21} } + +func (m *Node) GetID() string { + if m != nil { + return m.ID + } + return "" +} + +func (m *Node) GetURI() *URI { + if m != nil { + return m.URI + } + return nil +} + type NodeStateMessage struct { - URI *URI `protobuf:"bytes,1,opt,name=URI" json:"URI,omitempty"` - State string `protobuf:"bytes,2,opt,name=State,proto3" json:"State,omitempty"` + NodeID string `protobuf:"bytes,1,opt,name=NodeID,proto3" json:"NodeID,omitempty"` + State string `protobuf:"bytes,2,opt,name=State,proto3" json:"State,omitempty"` } func (m *NodeStateMessage) Reset() { *m = NodeStateMessage{} } func (m *NodeStateMessage) String() string { return proto.CompactTextString(m) } func (*NodeStateMessage) ProtoMessage() {} -func (*NodeStateMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{21} } +func (*NodeStateMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{22} } -func (m *NodeStateMessage) GetURI() *URI { +func (m *NodeStateMessage) GetNodeID() string { if m != nil { - return m.URI + return m.NodeID } - return nil + return "" } func (m *NodeStateMessage) GetState() string { @@ -698,7 +723,7 @@ func (m *NodeStateMessage) GetState() string { } type NodeStatus struct { - URI *URI `protobuf:"bytes,1,opt,name=URI" json:"URI,omitempty"` + Node *Node `protobuf:"bytes,1,opt,name=Node" json:"Node,omitempty"` MaxSlices *MaxSlices `protobuf:"bytes,2,opt,name=MaxSlices" json:"MaxSlices,omitempty"` Schema *Schema `protobuf:"bytes,3,opt,name=Schema" json:"Schema,omitempty"` } @@ -706,11 +731,11 @@ type NodeStatus struct { func (m *NodeStatus) Reset() { *m = NodeStatus{} } func (m *NodeStatus) String() string { return proto.CompactTextString(m) } func (*NodeStatus) ProtoMessage() {} -func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{22} } +func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{23} } -func (m *NodeStatus) GetURI() *URI { +func (m *NodeStatus) GetNode() *Node { if m != nil { - return m.URI + return m.Node } return nil } @@ -730,15 +755,22 @@ func (m *NodeStatus) GetSchema() *Schema { } type ClusterStatus struct { - State string `protobuf:"bytes,1,opt,name=State,proto3" json:"State,omitempty"` - NodeSet []*URI `protobuf:"bytes,2,rep,name=NodeSet" json:"NodeSet,omitempty"` - ClusterID string `protobuf:"bytes,3,opt,name=ClusterID,proto3" json:"ClusterID,omitempty"` + ClusterID string `protobuf:"bytes,1,opt,name=ClusterID,proto3" json:"ClusterID,omitempty"` + State string `protobuf:"bytes,2,opt,name=State,proto3" json:"State,omitempty"` + Nodes []*Node `protobuf:"bytes,3,rep,name=Nodes" json:"Nodes,omitempty"` } func (m *ClusterStatus) Reset() { *m = ClusterStatus{} } func (m *ClusterStatus) String() string { return proto.CompactTextString(m) } func (*ClusterStatus) ProtoMessage() {} -func (*ClusterStatus) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{23} } +func (*ClusterStatus) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{24} } + +func (m *ClusterStatus) GetClusterID() string { + if m != nil { + return m.ClusterID + } + return "" +} func (m *ClusterStatus) GetState() string { if m != nil { @@ -747,20 +779,13 @@ func (m *ClusterStatus) GetState() string { return "" } -func (m *ClusterStatus) GetNodeSet() []*URI { +func (m *ClusterStatus) GetNodes() []*Node { if m != nil { - return m.NodeSet + return m.Nodes } return nil } -func (m *ClusterStatus) GetClusterID() string { - if m != nil { - return m.ClusterID - } - return "" -} - type Field struct { Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` Type string `protobuf:"bytes,2,opt,name=Type,proto3" json:"Type,omitempty"` @@ -771,7 +796,7 @@ type Field struct { func (m *Field) Reset() { *m = Field{} } func (m *Field) String() string { return proto.CompactTextString(m) } func (*Field) ProtoMessage() {} -func (*Field) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{24} } +func (*Field) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{25} } func (m *Field) GetName() string { if m != nil { @@ -810,7 +835,7 @@ type CreateViewMessage struct { func (m *CreateViewMessage) Reset() { *m = CreateViewMessage{} } func (m *CreateViewMessage) String() string { return proto.CompactTextString(m) } func (*CreateViewMessage) ProtoMessage() {} -func (*CreateViewMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{25} } +func (*CreateViewMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{26} } func (m *CreateViewMessage) GetIndex() string { if m != nil { @@ -842,7 +867,7 @@ type DeleteViewMessage struct { func (m *DeleteViewMessage) Reset() { *m = DeleteViewMessage{} } func (m *DeleteViewMessage) String() string { return proto.CompactTextString(m) } func (*DeleteViewMessage) ProtoMessage() {} -func (*DeleteViewMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{26} } +func (*DeleteViewMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{27} } func (m *DeleteViewMessage) GetIndex() string { if m != nil { @@ -867,8 +892,8 @@ func (m *DeleteViewMessage) GetView() string { type ResizeInstruction struct { JobID int64 `protobuf:"varint,1,opt,name=JobID,proto3" json:"JobID,omitempty"` - URI *URI `protobuf:"bytes,2,opt,name=URI" json:"URI,omitempty"` - Coordinator *URI `protobuf:"bytes,3,opt,name=Coordinator" json:"Coordinator,omitempty"` + Node *Node `protobuf:"bytes,2,opt,name=Node" json:"Node,omitempty"` + Coordinator *Node `protobuf:"bytes,3,opt,name=Coordinator" json:"Coordinator,omitempty"` Sources []*ResizeSource `protobuf:"bytes,4,rep,name=Sources" json:"Sources,omitempty"` Schema *Schema `protobuf:"bytes,5,opt,name=Schema" json:"Schema,omitempty"` ClusterStatus *ClusterStatus `protobuf:"bytes,6,opt,name=ClusterStatus" json:"ClusterStatus,omitempty"` @@ -877,7 +902,7 @@ type ResizeInstruction struct { func (m *ResizeInstruction) Reset() { *m = ResizeInstruction{} } func (m *ResizeInstruction) String() string { return proto.CompactTextString(m) } func (*ResizeInstruction) ProtoMessage() {} -func (*ResizeInstruction) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{27} } +func (*ResizeInstruction) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{28} } func (m *ResizeInstruction) GetJobID() int64 { if m != nil { @@ -886,14 +911,14 @@ func (m *ResizeInstruction) GetJobID() int64 { return 0 } -func (m *ResizeInstruction) GetURI() *URI { +func (m *ResizeInstruction) GetNode() *Node { if m != nil { - return m.URI + return m.Node } return nil } -func (m *ResizeInstruction) GetCoordinator() *URI { +func (m *ResizeInstruction) GetCoordinator() *Node { if m != nil { return m.Coordinator } @@ -922,7 +947,7 @@ func (m *ResizeInstruction) GetClusterStatus() *ClusterStatus { } type ResizeSource struct { - URI *URI `protobuf:"bytes,1,opt,name=URI" json:"URI,omitempty"` + Node *Node `protobuf:"bytes,1,opt,name=Node" json:"Node,omitempty"` Index string `protobuf:"bytes,2,opt,name=Index,proto3" json:"Index,omitempty"` Frame string `protobuf:"bytes,3,opt,name=Frame,proto3" json:"Frame,omitempty"` View string `protobuf:"bytes,4,opt,name=View,proto3" json:"View,omitempty"` @@ -932,11 +957,11 @@ type ResizeSource struct { func (m *ResizeSource) Reset() { *m = ResizeSource{} } func (m *ResizeSource) String() string { return proto.CompactTextString(m) } func (*ResizeSource) ProtoMessage() {} -func (*ResizeSource) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{28} } +func (*ResizeSource) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{29} } -func (m *ResizeSource) GetURI() *URI { +func (m *ResizeSource) GetNode() *Node { if m != nil { - return m.URI + return m.Node } return nil } @@ -971,7 +996,7 @@ func (m *ResizeSource) GetSlice() uint64 { type ResizeInstructionComplete struct { JobID int64 `protobuf:"varint,1,opt,name=JobID,proto3" json:"JobID,omitempty"` - URI *URI `protobuf:"bytes,2,opt,name=URI" json:"URI,omitempty"` + Node *Node `protobuf:"bytes,2,opt,name=Node" json:"Node,omitempty"` Error string `protobuf:"bytes,3,opt,name=Error,proto3" json:"Error,omitempty"` } @@ -979,7 +1004,7 @@ func (m *ResizeInstructionComplete) Reset() { *m = ResizeInstructionComp func (m *ResizeInstructionComplete) String() string { return proto.CompactTextString(m) } func (*ResizeInstructionComplete) ProtoMessage() {} func (*ResizeInstructionComplete) Descriptor() ([]byte, []int) { - return fileDescriptorPrivate, []int{29} + return fileDescriptorPrivate, []int{30} } func (m *ResizeInstructionComplete) GetJobID() int64 { @@ -989,9 +1014,9 @@ func (m *ResizeInstructionComplete) GetJobID() int64 { return 0 } -func (m *ResizeInstructionComplete) GetURI() *URI { +func (m *ResizeInstructionComplete) GetNode() *Node { if m != nil { - return m.URI + return m.Node } return nil } @@ -1004,23 +1029,23 @@ func (m *ResizeInstructionComplete) GetError() string { } type SetCoordinatorMessage struct { - Old *URI `protobuf:"bytes,1,opt,name=Old" json:"Old,omitempty"` - New *URI `protobuf:"bytes,2,opt,name=New" json:"New,omitempty"` + Old *Node `protobuf:"bytes,1,opt,name=Old" json:"Old,omitempty"` + New *Node `protobuf:"bytes,2,opt,name=New" json:"New,omitempty"` } func (m *SetCoordinatorMessage) Reset() { *m = SetCoordinatorMessage{} } func (m *SetCoordinatorMessage) String() string { return proto.CompactTextString(m) } func (*SetCoordinatorMessage) ProtoMessage() {} -func (*SetCoordinatorMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{30} } +func (*SetCoordinatorMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{31} } -func (m *SetCoordinatorMessage) GetOld() *URI { +func (m *SetCoordinatorMessage) GetOld() *Node { if m != nil { return m.Old } return nil } -func (m *SetCoordinatorMessage) GetNew() *URI { +func (m *SetCoordinatorMessage) GetNew() *Node { if m != nil { return m.New } @@ -1028,21 +1053,14 @@ func (m *SetCoordinatorMessage) GetNew() *URI { } type Topology struct { - NodeSet []*URI `protobuf:"bytes,1,rep,name=NodeSet" json:"NodeSet,omitempty"` - ClusterID string `protobuf:"bytes,2,opt,name=ClusterID,proto3" json:"ClusterID,omitempty"` + ClusterID string `protobuf:"bytes,1,opt,name=ClusterID,proto3" json:"ClusterID,omitempty"` + NodeIDs []string `protobuf:"bytes,2,rep,name=NodeIDs" json:"NodeIDs,omitempty"` } func (m *Topology) Reset() { *m = Topology{} } func (m *Topology) String() string { return proto.CompactTextString(m) } func (*Topology) ProtoMessage() {} -func (*Topology) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{31} } - -func (m *Topology) GetNodeSet() []*URI { - if m != nil { - return m.NodeSet - } - return nil -} +func (*Topology) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{32} } func (m *Topology) GetClusterID() string { if m != nil { @@ -1051,6 +1069,13 @@ func (m *Topology) GetClusterID() string { return "" } +func (m *Topology) GetNodeIDs() []string { + if m != nil { + return m.NodeIDs + } + return nil +} + func init() { proto.RegisterType((*IndexMeta)(nil), "internal.IndexMeta") proto.RegisterType((*FrameMeta)(nil), "internal.FrameMeta") @@ -1073,6 +1098,7 @@ func init() { proto.RegisterType((*CreateInputDefinitionMessage)(nil), "internal.CreateInputDefinitionMessage") proto.RegisterType((*DeleteInputDefinitionMessage)(nil), "internal.DeleteInputDefinitionMessage") proto.RegisterType((*URI)(nil), "internal.URI") + proto.RegisterType((*Node)(nil), "internal.Node") proto.RegisterType((*NodeStateMessage)(nil), "internal.NodeStateMessage") proto.RegisterType((*NodeStatus)(nil), "internal.NodeStatus") proto.RegisterType((*ClusterStatus)(nil), "internal.ClusterStatus") @@ -1933,6 +1959,40 @@ func (m *URI) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *Node) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Node) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.ID) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintPrivate(dAtA, i, uint64(len(m.ID))) + i += copy(dAtA[i:], m.ID) + } + if m.URI != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintPrivate(dAtA, i, uint64(m.URI.Size())) + n11, err := m.URI.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n11 + } + return i, nil +} + func (m *NodeStateMessage) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1948,15 +2008,11 @@ func (m *NodeStateMessage) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.URI != nil { + if len(m.NodeID) > 0 { dAtA[i] = 0xa i++ - i = encodeVarintPrivate(dAtA, i, uint64(m.URI.Size())) - n11, err := m.URI.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n11 + i = encodeVarintPrivate(dAtA, i, uint64(len(m.NodeID))) + i += copy(dAtA[i:], m.NodeID) } if len(m.State) > 0 { dAtA[i] = 0x12 @@ -1982,11 +2038,11 @@ func (m *NodeStatus) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.URI != nil { + if m.Node != nil { dAtA[i] = 0xa i++ - i = encodeVarintPrivate(dAtA, i, uint64(m.URI.Size())) - n12, err := m.URI.MarshalTo(dAtA[i:]) + i = encodeVarintPrivate(dAtA, i, uint64(m.Node.Size())) + n12, err := m.Node.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -2030,15 +2086,21 @@ func (m *ClusterStatus) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.State) > 0 { + if len(m.ClusterID) > 0 { dAtA[i] = 0xa i++ + i = encodeVarintPrivate(dAtA, i, uint64(len(m.ClusterID))) + i += copy(dAtA[i:], m.ClusterID) + } + if len(m.State) > 0 { + dAtA[i] = 0x12 + i++ i = encodeVarintPrivate(dAtA, i, uint64(len(m.State))) i += copy(dAtA[i:], m.State) } - if len(m.NodeSet) > 0 { - for _, msg := range m.NodeSet { - dAtA[i] = 0x12 + if len(m.Nodes) > 0 { + for _, msg := range m.Nodes { + dAtA[i] = 0x1a i++ i = encodeVarintPrivate(dAtA, i, uint64(msg.Size())) n, err := msg.MarshalTo(dAtA[i:]) @@ -2048,12 +2110,6 @@ func (m *ClusterStatus) MarshalTo(dAtA []byte) (int, error) { i += n } } - if len(m.ClusterID) > 0 { - dAtA[i] = 0x1a - i++ - i = encodeVarintPrivate(dAtA, i, uint64(len(m.ClusterID))) - i += copy(dAtA[i:], m.ClusterID) - } return i, nil } @@ -2189,11 +2245,11 @@ func (m *ResizeInstruction) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintPrivate(dAtA, i, uint64(m.JobID)) } - if m.URI != nil { + if m.Node != nil { dAtA[i] = 0x12 i++ - i = encodeVarintPrivate(dAtA, i, uint64(m.URI.Size())) - n15, err := m.URI.MarshalTo(dAtA[i:]) + i = encodeVarintPrivate(dAtA, i, uint64(m.Node.Size())) + n15, err := m.Node.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -2259,11 +2315,11 @@ func (m *ResizeSource) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.URI != nil { + if m.Node != nil { dAtA[i] = 0xa i++ - i = encodeVarintPrivate(dAtA, i, uint64(m.URI.Size())) - n19, err := m.URI.MarshalTo(dAtA[i:]) + i = encodeVarintPrivate(dAtA, i, uint64(m.Node.Size())) + n19, err := m.Node.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -2315,11 +2371,11 @@ func (m *ResizeInstructionComplete) MarshalTo(dAtA []byte) (int, error) { i++ i = encodeVarintPrivate(dAtA, i, uint64(m.JobID)) } - if m.URI != nil { + if m.Node != nil { dAtA[i] = 0x12 i++ - i = encodeVarintPrivate(dAtA, i, uint64(m.URI.Size())) - n20, err := m.URI.MarshalTo(dAtA[i:]) + i = encodeVarintPrivate(dAtA, i, uint64(m.Node.Size())) + n20, err := m.Node.MarshalTo(dAtA[i:]) if err != nil { return 0, err } @@ -2387,24 +2443,27 @@ func (m *Topology) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.NodeSet) > 0 { - for _, msg := range m.NodeSet { - dAtA[i] = 0xa - i++ - i = encodeVarintPrivate(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } - } if len(m.ClusterID) > 0 { - dAtA[i] = 0x12 + dAtA[i] = 0xa i++ i = encodeVarintPrivate(dAtA, i, uint64(len(m.ClusterID))) i += copy(dAtA[i:], m.ClusterID) } + if len(m.NodeIDs) > 0 { + for _, s := range m.NodeIDs { + dAtA[i] = 0x12 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } return i, nil } @@ -2808,11 +2867,25 @@ func (m *URI) Size() (n int) { return n } +func (m *Node) Size() (n int) { + var l int + _ = l + l = len(m.ID) + if l > 0 { + n += 1 + l + sovPrivate(uint64(l)) + } + if m.URI != nil { + l = m.URI.Size() + n += 1 + l + sovPrivate(uint64(l)) + } + return n +} + func (m *NodeStateMessage) Size() (n int) { var l int _ = l - if m.URI != nil { - l = m.URI.Size() + l = len(m.NodeID) + if l > 0 { n += 1 + l + sovPrivate(uint64(l)) } l = len(m.State) @@ -2825,8 +2898,8 @@ func (m *NodeStateMessage) Size() (n int) { func (m *NodeStatus) Size() (n int) { var l int _ = l - if m.URI != nil { - l = m.URI.Size() + if m.Node != nil { + l = m.Node.Size() n += 1 + l + sovPrivate(uint64(l)) } if m.MaxSlices != nil { @@ -2843,20 +2916,20 @@ func (m *NodeStatus) Size() (n int) { func (m *ClusterStatus) Size() (n int) { var l int _ = l + l = len(m.ClusterID) + if l > 0 { + n += 1 + l + sovPrivate(uint64(l)) + } l = len(m.State) if l > 0 { n += 1 + l + sovPrivate(uint64(l)) } - if len(m.NodeSet) > 0 { - for _, e := range m.NodeSet { + if len(m.Nodes) > 0 { + for _, e := range m.Nodes { l = e.Size() n += 1 + l + sovPrivate(uint64(l)) } } - l = len(m.ClusterID) - if l > 0 { - n += 1 + l + sovPrivate(uint64(l)) - } return n } @@ -2922,8 +2995,8 @@ func (m *ResizeInstruction) Size() (n int) { if m.JobID != 0 { n += 1 + sovPrivate(uint64(m.JobID)) } - if m.URI != nil { - l = m.URI.Size() + if m.Node != nil { + l = m.Node.Size() n += 1 + l + sovPrivate(uint64(l)) } if m.Coordinator != nil { @@ -2950,8 +3023,8 @@ func (m *ResizeInstruction) Size() (n int) { func (m *ResizeSource) Size() (n int) { var l int _ = l - if m.URI != nil { - l = m.URI.Size() + if m.Node != nil { + l = m.Node.Size() n += 1 + l + sovPrivate(uint64(l)) } l = len(m.Index) @@ -2978,8 +3051,8 @@ func (m *ResizeInstructionComplete) Size() (n int) { if m.JobID != 0 { n += 1 + sovPrivate(uint64(m.JobID)) } - if m.URI != nil { - l = m.URI.Size() + if m.Node != nil { + l = m.Node.Size() n += 1 + l + sovPrivate(uint64(l)) } l = len(m.Error) @@ -3006,16 +3079,16 @@ func (m *SetCoordinatorMessage) Size() (n int) { func (m *Topology) Size() (n int) { var l int _ = l - if len(m.NodeSet) > 0 { - for _, e := range m.NodeSet { - l = e.Size() - n += 1 + l + sovPrivate(uint64(l)) - } - } l = len(m.ClusterID) if l > 0 { n += 1 + l + sovPrivate(uint64(l)) } + if len(m.NodeIDs) > 0 { + for _, s := range m.NodeIDs { + l = len(s) + n += 1 + l + sovPrivate(uint64(l)) + } + } return n } @@ -5941,7 +6014,7 @@ func (m *URI) Unmarshal(dAtA []byte) error { } return nil } -func (m *NodeStateMessage) Unmarshal(dAtA []byte) error { +func (m *Node) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -5964,13 +6037,42 @@ func (m *NodeStateMessage) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: NodeStateMessage: wiretype end group for non-group") + return fmt.Errorf("proto: Node: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: NodeStateMessage: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Node: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrivate + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPrivate + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field URI", wireType) } @@ -6003,6 +6105,85 @@ func (m *NodeStateMessage) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPrivate(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPrivate + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NodeStateMessage) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrivate + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeStateMessage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeStateMessage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrivate + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPrivate + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NodeID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) @@ -6084,7 +6265,7 @@ func (m *NodeStatus) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field URI", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Node", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -6108,10 +6289,10 @@ func (m *NodeStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.URI == nil { - m.URI = &URI{} + if m.Node == nil { + m.Node = &Node{} } - if err := m.URI.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Node.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -6232,6 +6413,35 @@ func (m *ClusterStatus) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClusterID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrivate + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPrivate + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClusterID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) } @@ -6260,9 +6470,9 @@ func (m *ClusterStatus) Unmarshal(dAtA []byte) error { } m.State = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeSet", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Nodes", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -6286,40 +6496,11 @@ func (m *ClusterStatus) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.NodeSet = append(m.NodeSet, &URI{}) - if err := m.NodeSet[len(m.NodeSet)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Nodes = append(m.Nodes, &Node{}) + if err := m.Nodes[len(m.Nodes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ClusterID", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPrivate - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthPrivate - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ClusterID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPrivate(dAtA[iNdEx:]) @@ -6811,7 +6992,7 @@ func (m *ResizeInstruction) Unmarshal(dAtA []byte) error { } case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field URI", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Node", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -6835,10 +7016,10 @@ func (m *ResizeInstruction) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.URI == nil { - m.URI = &URI{} + if m.Node == nil { + m.Node = &Node{} } - if err := m.URI.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Node.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -6869,7 +7050,7 @@ func (m *ResizeInstruction) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Coordinator == nil { - m.Coordinator = &URI{} + m.Coordinator = &Node{} } if err := m.Coordinator.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -7024,7 +7205,7 @@ func (m *ResizeSource) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field URI", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Node", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -7048,10 +7229,10 @@ func (m *ResizeSource) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.URI == nil { - m.URI = &URI{} + if m.Node == nil { + m.Node = &Node{} } - if err := m.URI.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Node.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -7232,7 +7413,7 @@ func (m *ResizeInstructionComplete) Unmarshal(dAtA []byte) error { } case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field URI", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Node", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -7256,10 +7437,10 @@ func (m *ResizeInstructionComplete) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.URI == nil { - m.URI = &URI{} + if m.Node == nil { + m.Node = &Node{} } - if err := m.URI.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Node.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -7369,7 +7550,7 @@ func (m *SetCoordinatorMessage) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Old == nil { - m.Old = &URI{} + m.Old = &Node{} } if err := m.Old.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -7402,7 +7583,7 @@ func (m *SetCoordinatorMessage) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.New == nil { - m.New = &URI{} + m.New = &Node{} } if err := m.New.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -7459,37 +7640,6 @@ func (m *Topology) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeSet", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPrivate - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthPrivate - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.NodeSet = append(m.NodeSet, &URI{}) - if err := m.NodeSet[len(m.NodeSet)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ClusterID", wireType) } @@ -7518,6 +7668,35 @@ func (m *Topology) Unmarshal(dAtA []byte) error { } m.ClusterID = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeIDs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrivate + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPrivate + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NodeIDs = append(m.NodeIDs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipPrivate(dAtA[iNdEx:]) @@ -7647,82 +7826,84 @@ var ( func init() { proto.RegisterFile("private.proto", fileDescriptorPrivate) } var fileDescriptorPrivate = []byte{ - // 1229 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0x67, 0xbd, 0xb6, 0x63, 0x3f, 0xc7, 0x8d, 0x33, 0xa4, 0xc1, 0x89, 0x22, 0xd7, 0xcc, 0x81, - 0x84, 0x4a, 0x04, 0x70, 0x25, 0x04, 0x41, 0x95, 0xa0, 0xb1, 0xab, 0x2e, 0x90, 0xa4, 0x1d, 0xa7, - 0x45, 0x70, 0x40, 0x9a, 0xd8, 0x43, 0xb2, 0xca, 0x7a, 0xd7, 0xec, 0x8e, 0x93, 0xb8, 0x07, 0x6e, - 0x70, 0x80, 0x3b, 0xe2, 0xce, 0x97, 0xe1, 0xc8, 0x47, 0x40, 0xe1, 0x43, 0x20, 0x71, 0x01, 0xcd, - 0xbf, 0xdd, 0xf5, 0xda, 0x4e, 0x9a, 0x88, 0xdb, 0xbe, 0x37, 0xbf, 0xf7, 0xe6, 0x37, 0xef, 0xdf, - 0xcc, 0x42, 0x75, 0x18, 0xba, 0x67, 0x94, 0xb3, 0xed, 0x61, 0x18, 0xf0, 0x00, 0x95, 0x5c, 0x9f, - 0xb3, 0xd0, 0xa7, 0x1e, 0x3e, 0x80, 0xb2, 0xe3, 0xf7, 0xd9, 0xc5, 0x1e, 0xe3, 0x14, 0x35, 0xa1, - 0xb2, 0x1b, 0x78, 0xa3, 0x81, 0xff, 0x05, 0x3d, 0x62, 0x5e, 0xdd, 0x6a, 0x5a, 0x5b, 0x65, 0x92, - 0x56, 0x09, 0xc4, 0xa1, 0x3b, 0x60, 0xcf, 0x46, 0xd4, 0xe7, 0xa3, 0x41, 0x3d, 0xa7, 0x10, 0x29, - 0x15, 0xfe, 0xc7, 0x82, 0xf2, 0xe3, 0x90, 0x0e, 0x98, 0xf4, 0xb8, 0x0e, 0x25, 0x12, 0x9c, 0xa7, - 0xdd, 0xc5, 0x32, 0x7a, 0x0b, 0xee, 0x38, 0xfe, 0x19, 0x0b, 0x23, 0xd6, 0xf1, 0xe9, 0x91, 0xc7, - 0xfa, 0xd2, 0x5d, 0x89, 0x64, 0xb4, 0x68, 0x03, 0xca, 0xbb, 0xb4, 0x77, 0xc2, 0x0e, 0xc7, 0x43, - 0x56, 0xb7, 0xa5, 0x93, 0x44, 0x11, 0xaf, 0x76, 0xdd, 0x97, 0xac, 0x9e, 0x6f, 0x5a, 0x5b, 0x55, - 0x92, 0x28, 0xb2, 0x7c, 0x0b, 0x53, 0x7c, 0x11, 0x86, 0x45, 0x42, 0xfd, 0xe3, 0x98, 0x43, 0x51, - 0x72, 0x98, 0xd0, 0xa1, 0x4d, 0x28, 0x3e, 0x76, 0x99, 0xd7, 0x8f, 0xea, 0x0b, 0x4d, 0x7b, 0xab, - 0xd2, 0x5a, 0xda, 0x36, 0xf1, 0xdb, 0x96, 0x7a, 0xa2, 0x97, 0x31, 0x86, 0x3b, 0xce, 0x60, 0x18, - 0x84, 0x9c, 0xb0, 0x68, 0x18, 0xf8, 0x11, 0x43, 0x35, 0xb0, 0x3b, 0x61, 0xa8, 0xcf, 0x2e, 0x3e, - 0xf1, 0xf7, 0x50, 0x7b, 0xe4, 0x05, 0xbd, 0xd3, 0x36, 0xe5, 0x94, 0xb0, 0xef, 0x46, 0x2c, 0xe2, - 0x68, 0x05, 0x0a, 0x32, 0x0b, 0x1a, 0xa7, 0x04, 0xa1, 0x95, 0x91, 0xd4, 0x61, 0x56, 0x82, 0xd0, - 0x4a, 0x7b, 0x19, 0x8a, 0x3c, 0x51, 0x82, 0xd0, 0x76, 0x3d, 0xb7, 0xa7, 0x42, 0x90, 0x27, 0x4a, - 0x40, 0x08, 0xf2, 0x2f, 0x5c, 0x76, 0xae, 0xcf, 0x2d, 0xbf, 0xb1, 0x03, 0xcb, 0xa9, 0xfd, 0x35, - 0xcd, 0x55, 0x28, 0x92, 0xe0, 0xdc, 0x69, 0x47, 0x75, 0xab, 0x69, 0x6f, 0xe5, 0x89, 0x96, 0x64, - 0x74, 0x65, 0xfa, 0xc5, 0x52, 0x4e, 0x2e, 0x25, 0x0a, 0xbc, 0x06, 0x05, 0x19, 0x6a, 0x71, 0xca, - 0xc4, 0x56, 0x7c, 0xe2, 0x7f, 0x2d, 0x28, 0xef, 0xd1, 0x0b, 0x49, 0x23, 0x42, 0x0f, 0xa1, 0xd4, - 0xe5, 0xd4, 0xef, 0xd3, 0xb0, 0x2f, 0x41, 0x95, 0xd6, 0x9b, 0x49, 0x08, 0x63, 0xd8, 0xb6, 0xc1, - 0x74, 0x7c, 0x1e, 0x8e, 0x49, 0x6c, 0x82, 0x76, 0x60, 0x41, 0xd7, 0x84, 0xe4, 0x50, 0x69, 0x35, - 0x67, 0x59, 0xc7, 0x65, 0x23, 0x8c, 0x8d, 0xc1, 0xfa, 0xc7, 0x50, 0x9d, 0x70, 0x2b, 0xb8, 0x9e, - 0xb2, 0xb1, 0xc9, 0xc8, 0x29, 0x1b, 0x8b, 0xd8, 0x9d, 0x51, 0x6f, 0xa4, 0xe2, 0x9c, 0x27, 0x4a, - 0xd8, 0xc9, 0x7d, 0x68, 0xad, 0xef, 0xc0, 0x62, 0xda, 0xeb, 0x4d, 0x6c, 0xf1, 0x37, 0x80, 0x76, - 0x43, 0x46, 0x39, 0x93, 0xf4, 0xf6, 0x58, 0x14, 0xd1, 0x63, 0x36, 0x3f, 0xd3, 0x2a, 0x7b, 0xb9, - 0x74, 0xf6, 0x36, 0xa0, 0xec, 0x44, 0xe6, 0xe0, 0xb6, 0xac, 0xcb, 0x44, 0x81, 0xef, 0x03, 0x6a, - 0x33, 0x8f, 0x71, 0xa6, 0xfb, 0xf7, 0x0a, 0xff, 0xb8, 0x6b, 0xb8, 0x5c, 0x8f, 0x45, 0x9b, 0x90, - 0x17, 0xad, 0x2b, 0xa9, 0x54, 0x5a, 0xaf, 0x27, 0x91, 0x8e, 0xe7, 0x04, 0x91, 0x00, 0xec, 0x1a, - 0xa7, 0xba, 0xdd, 0xaf, 0x39, 0xe0, 0x8c, 0x52, 0x36, 0x5b, 0xd9, 0xd9, 0xad, 0xe2, 0x01, 0xa2, - 0xb7, 0xfa, 0xc4, 0x9c, 0xf5, 0xb6, 0x5b, 0xe1, 0xaf, 0xb5, 0x56, 0xb4, 0xc4, 0xbe, 0x58, 0x55, - 0x36, 0xf2, 0x7b, 0xfe, 0x91, 0x33, 0x3c, 0x84, 0x6f, 0xd1, 0x43, 0x51, 0xdd, 0x6e, 0xda, 0xc2, - 0xb7, 0x14, 0xf0, 0x03, 0x28, 0x76, 0x7b, 0x27, 0x6c, 0x40, 0xd1, 0xdb, 0xa2, 0x50, 0xfb, 0xec, - 0x82, 0x45, 0xba, 0xcc, 0x97, 0x32, 0xe1, 0x23, 0x66, 0x1d, 0xff, 0x6c, 0x69, 0xf6, 0x73, 0x18, - 0x15, 0xe5, 0xde, 0x51, 0x3d, 0x3f, 0x35, 0x71, 0x84, 0x9e, 0xe8, 0x65, 0xd4, 0x81, 0x9a, 0xe3, - 0x0f, 0x47, 0xbc, 0xcd, 0xbe, 0x75, 0x7d, 0x97, 0xbb, 0x81, 0x1f, 0xd5, 0x8b, 0xd2, 0x64, 0x2d, - 0xbd, 0xf5, 0x04, 0x82, 0x4c, 0x99, 0xe0, 0x1f, 0x2d, 0x58, 0xca, 0x28, 0xaf, 0xe1, 0x95, 0xbb, - 0x9a, 0xd7, 0x07, 0xf1, 0xc8, 0xb4, 0x25, 0xb0, 0x31, 0x97, 0xcd, 0xe4, 0x04, 0xfd, 0xcd, 0x82, - 0x95, 0x59, 0x80, 0x99, 0x6c, 0x1a, 0x00, 0x4f, 0x43, 0x77, 0x40, 0xc3, 0xf1, 0xe7, 0x6c, 0xac, - 0x6f, 0x8f, 0x94, 0x06, 0x7d, 0x09, 0xab, 0x19, 0x5f, 0x9f, 0xf6, 0x54, 0x88, 0x14, 0xa9, 0x7b, - 0x73, 0x49, 0x29, 0x1c, 0x99, 0x63, 0x8e, 0xff, 0xb6, 0xe0, 0xee, 0xcc, 0xa5, 0xa4, 0xfa, 0xac, - 0x74, 0xa1, 0xdf, 0x87, 0xda, 0x0b, 0x31, 0x18, 0xda, 0x2c, 0xe2, 0xae, 0x4f, 0x05, 0x52, 0x97, - 0xe7, 0x94, 0x1e, 0x39, 0x50, 0x92, 0xba, 0x3d, 0x3a, 0xd4, 0x34, 0xdf, 0xb9, 0x86, 0xe6, 0xb6, - 0xc1, 0xeb, 0xb9, 0x69, 0x44, 0x41, 0x46, 0xce, 0x71, 0x73, 0x29, 0x48, 0x41, 0x4c, 0xc4, 0x09, - 0x83, 0x1b, 0x4d, 0xb5, 0x00, 0x36, 0xcc, 0x24, 0x99, 0x60, 0x72, 0x75, 0x4f, 0x7e, 0x04, 0x90, - 0x40, 0x75, 0xbb, 0x5f, 0x51, 0x9f, 0x29, 0x30, 0x7e, 0x02, 0x1b, 0x66, 0xcc, 0xdd, 0x60, 0x43, - 0x53, 0x2d, 0xb9, 0xa4, 0x5a, 0x70, 0x07, 0xec, 0xe7, 0xc4, 0x11, 0x57, 0x9d, 0xec, 0x56, 0x93, - 0x22, 0x2d, 0x09, 0x93, 0x27, 0x41, 0xc4, 0x8d, 0x89, 0xf8, 0x16, 0xba, 0xa7, 0x41, 0xc8, 0x25, - 0xe3, 0x2a, 0x91, 0xdf, 0xd8, 0x81, 0xda, 0x7e, 0xd0, 0x67, 0x5d, 0x4e, 0x79, 0x3c, 0x89, 0xee, - 0x49, 0xd7, 0xd2, 0x61, 0xa5, 0x55, 0x4d, 0x0e, 0xf6, 0x9c, 0x38, 0x44, 0x6e, 0x2a, 0x06, 0xbc, - 0x30, 0x30, 0x43, 0x49, 0x0a, 0xf8, 0x27, 0x0b, 0xc0, 0xf8, 0x1a, 0x45, 0xd7, 0x7b, 0x79, 0x3f, - 0x75, 0xa7, 0x4e, 0x0f, 0xab, 0x78, 0x89, 0xa4, 0x6e, 0xde, 0x2d, 0x33, 0x9b, 0x74, 0xd4, 0x6b, - 0x09, 0x5e, 0xe9, 0xf5, 0xf9, 0x29, 0xf6, 0xa0, 0xba, 0xeb, 0x8d, 0x22, 0xce, 0x42, 0x4d, 0x27, - 0xe6, 0x6c, 0xa5, 0x38, 0xa3, 0x4d, 0x58, 0x90, 0x94, 0x19, 0xd7, 0x23, 0x20, 0x43, 0xd4, 0xac, - 0xca, 0xa7, 0x83, 0xf2, 0xe7, 0xb4, 0xe3, 0x67, 0x9b, 0x51, 0xe0, 0x2e, 0x14, 0xe6, 0xf7, 0x35, - 0x82, 0xbc, 0x7c, 0xec, 0xe9, 0x54, 0xc8, 0x77, 0x5e, 0x0d, 0xec, 0x3d, 0x57, 0xd5, 0x8e, 0x4d, - 0xc4, 0xa7, 0xd4, 0xd0, 0x0b, 0x59, 0xdb, 0x42, 0x43, 0xc5, 0x35, 0xb7, 0xac, 0x8a, 0x53, 0xcc, - 0xe5, 0xdb, 0x5c, 0x48, 0xe6, 0xbd, 0x64, 0xa7, 0xde, 0x4b, 0x5d, 0x58, 0x56, 0x05, 0xf8, 0x7f, - 0x3a, 0xfd, 0x25, 0x07, 0xcb, 0x84, 0x45, 0xee, 0x4b, 0xe6, 0xf8, 0x11, 0x0f, 0x47, 0xf1, 0xf0, - 0xf8, 0x2c, 0x38, 0x72, 0xda, 0xd2, 0xab, 0x4d, 0x94, 0x60, 0xca, 0x22, 0x37, 0xb7, 0x2c, 0xde, - 0x15, 0xcf, 0xf6, 0x20, 0xec, 0x8b, 0x09, 0x12, 0x84, 0x3a, 0xd1, 0x19, 0x60, 0x1a, 0x81, 0xde, - 0x83, 0x85, 0x6e, 0x30, 0x0a, 0x7b, 0xf1, 0xf5, 0xb2, 0x9a, 0x80, 0x15, 0x2b, 0xb5, 0x4c, 0x0c, - 0x2c, 0x55, 0x46, 0x85, 0xab, 0xcb, 0x08, 0x3d, 0xcc, 0x94, 0x91, 0x7c, 0x50, 0x57, 0x5a, 0x6f, - 0x24, 0x06, 0x13, 0xcb, 0x64, 0x12, 0x8d, 0x7f, 0xb0, 0x60, 0x31, 0x4d, 0xe1, 0x95, 0x5a, 0x4b, - 0xa5, 0x22, 0x37, 0x33, 0x15, 0xf6, 0xac, 0x54, 0xe4, 0x93, 0x54, 0x24, 0x6f, 0xaf, 0x42, 0xea, - 0xed, 0x85, 0x4f, 0x60, 0x6d, 0x2a, 0x3f, 0xbb, 0xc1, 0x60, 0x28, 0x0a, 0xe1, 0xb6, 0x79, 0x5a, - 0x81, 0x42, 0x27, 0x0c, 0x75, 0x86, 0xca, 0x44, 0x09, 0xf8, 0x2b, 0xb8, 0xdb, 0x65, 0x3c, 0x95, - 0x9e, 0xd4, 0x50, 0x39, 0xf0, 0xfa, 0x73, 0x4e, 0x7e, 0xe0, 0xf5, 0x05, 0x60, 0x9f, 0x9d, 0xcf, - 0xd9, 0x70, 0x9f, 0x9d, 0xe3, 0x67, 0x50, 0x3a, 0x0c, 0x86, 0x81, 0x17, 0x1c, 0x8f, 0xd3, 0x7d, - 0x6b, 0xbd, 0x7a, 0xdf, 0xe6, 0x32, 0x7d, 0xfb, 0xa8, 0xf6, 0xfb, 0x65, 0xc3, 0xfa, 0xe3, 0xb2, - 0x61, 0xfd, 0x79, 0xd9, 0xb0, 0x7e, 0xfd, 0xab, 0xf1, 0xda, 0x51, 0x51, 0xfe, 0x52, 0x3e, 0xf8, - 0x2f, 0x00, 0x00, 0xff, 0xff, 0x59, 0x94, 0x30, 0x6d, 0x63, 0x0e, 0x00, 0x00, + // 1258 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x5b, 0x6f, 0x1b, 0x45, + 0x14, 0x66, 0xbd, 0xb6, 0x63, 0x1f, 0xd7, 0xa9, 0x33, 0xb4, 0xc1, 0xad, 0x22, 0xd7, 0x8c, 0x10, + 0x0d, 0x95, 0x88, 0x8a, 0x2b, 0x71, 0x09, 0xaa, 0x54, 0x12, 0xbb, 0xea, 0x02, 0x49, 0xcb, 0x38, + 0x2d, 0x12, 0x48, 0x48, 0x13, 0x7b, 0x48, 0x57, 0x59, 0xef, 0x9a, 0xdd, 0x75, 0x12, 0xf7, 0x81, + 0x47, 0x84, 0x84, 0x78, 0x47, 0xbc, 0xf2, 0x67, 0x78, 0xe4, 0x27, 0xa0, 0xf0, 0x23, 0x90, 0x78, + 0x01, 0x9d, 0xb9, 0xec, 0xae, 0xaf, 0x21, 0x85, 0xb7, 0x3d, 0xdf, 0xb9, 0xcc, 0x37, 0xe7, 0x9c, + 0x39, 0x33, 0x0b, 0xd5, 0x61, 0xe8, 0x9e, 0xf0, 0x58, 0x6c, 0x0d, 0xc3, 0x20, 0x0e, 0x48, 0xc9, + 0xf5, 0x63, 0x11, 0xfa, 0xdc, 0xa3, 0x8f, 0xa1, 0xec, 0xf8, 0x7d, 0x71, 0xb6, 0x27, 0x62, 0x4e, + 0x9a, 0x50, 0xd9, 0x0d, 0xbc, 0xd1, 0xc0, 0xff, 0x94, 0x1f, 0x0a, 0xaf, 0x6e, 0x35, 0xad, 0xcd, + 0x32, 0xcb, 0x42, 0x68, 0x71, 0xe0, 0x0e, 0xc4, 0x67, 0x23, 0xee, 0xc7, 0xa3, 0x41, 0x3d, 0xa7, + 0x2c, 0x32, 0x10, 0xfd, 0xcb, 0x82, 0xf2, 0xc3, 0x90, 0x0f, 0x84, 0x8c, 0x78, 0x13, 0x4a, 0x2c, + 0x38, 0xcd, 0x86, 0x4b, 0x64, 0xf2, 0x26, 0xac, 0x3a, 0xfe, 0x89, 0x08, 0x23, 0xd1, 0xf1, 0xf9, + 0xa1, 0x27, 0xfa, 0x32, 0x5c, 0x89, 0x4d, 0xa1, 0x64, 0x03, 0xca, 0xbb, 0xbc, 0xf7, 0x5c, 0x1c, + 0x8c, 0x87, 0xa2, 0x6e, 0xcb, 0x20, 0x29, 0x90, 0x68, 0xbb, 0xee, 0x0b, 0x51, 0xcf, 0x37, 0xad, + 0xcd, 0x2a, 0x4b, 0x81, 0x69, 0xbe, 0x85, 0x19, 0xbe, 0x84, 0xc2, 0x15, 0xc6, 0xfd, 0xa3, 0x84, + 0x43, 0x51, 0x72, 0x98, 0xc0, 0xc8, 0x6d, 0x28, 0x3e, 0x74, 0x85, 0xd7, 0x8f, 0xea, 0x2b, 0x4d, + 0x7b, 0xb3, 0xd2, 0xba, 0xba, 0x65, 0xf2, 0xb7, 0x25, 0x71, 0xa6, 0xd5, 0x94, 0xc2, 0xaa, 0x33, + 0x18, 0x06, 0x61, 0xcc, 0x44, 0x34, 0x0c, 0xfc, 0x48, 0x90, 0x1a, 0xd8, 0x9d, 0x30, 0xd4, 0x7b, + 0xc7, 0x4f, 0xfa, 0x2d, 0xd4, 0x76, 0xbc, 0xa0, 0x77, 0xdc, 0xe6, 0x31, 0x67, 0xe2, 0x9b, 0x91, + 0x88, 0x62, 0x72, 0x0d, 0x0a, 0xb2, 0x0a, 0xda, 0x4e, 0x09, 0x88, 0xca, 0x4c, 0xea, 0x34, 0x2b, + 0x01, 0x51, 0xe9, 0x2f, 0x53, 0x91, 0x67, 0x4a, 0x40, 0xb4, 0xeb, 0xb9, 0x3d, 0x95, 0x82, 0x3c, + 0x53, 0x02, 0x21, 0x90, 0x7f, 0xe6, 0x8a, 0x53, 0xbd, 0x6f, 0xf9, 0x4d, 0x1d, 0x58, 0xcb, 0xac, + 0xaf, 0x69, 0xae, 0x43, 0x91, 0x05, 0xa7, 0x4e, 0x3b, 0xaa, 0x5b, 0x4d, 0x7b, 0x33, 0xcf, 0xb4, + 0x24, 0xb3, 0x2b, 0xcb, 0x8f, 0xaa, 0x9c, 0x54, 0xa5, 0x00, 0xbd, 0x01, 0x05, 0x99, 0x6a, 0xdc, + 0x65, 0xea, 0x8b, 0x9f, 0xf4, 0x6f, 0x0b, 0xca, 0x7b, 0xfc, 0x4c, 0xd2, 0x88, 0xc8, 0x7d, 0x28, + 0x75, 0x63, 0xee, 0xf7, 0x79, 0xd8, 0x97, 0x46, 0x95, 0xd6, 0xeb, 0x69, 0x0a, 0x13, 0xb3, 0x2d, + 0x63, 0xd3, 0xf1, 0xe3, 0x70, 0xcc, 0x12, 0x17, 0xb2, 0x0d, 0x2b, 0xba, 0x27, 0x24, 0x87, 0x4a, + 0xab, 0x39, 0xcf, 0x3b, 0x69, 0x1b, 0x74, 0x36, 0x0e, 0x37, 0x3f, 0x84, 0xea, 0x44, 0x58, 0xe4, + 0x7a, 0x2c, 0xc6, 0xa6, 0x22, 0xc7, 0x62, 0x8c, 0xb9, 0x3b, 0xe1, 0xde, 0x48, 0xe5, 0x39, 0xcf, + 0x94, 0xb0, 0x9d, 0x7b, 0xdf, 0xba, 0xb9, 0x0d, 0x57, 0xb2, 0x51, 0x2f, 0xe3, 0x4b, 0xbf, 0x02, + 0xb2, 0x1b, 0x0a, 0x1e, 0x0b, 0x49, 0x6f, 0x4f, 0x44, 0x11, 0x3f, 0x12, 0x8b, 0x2b, 0xad, 0xaa, + 0x97, 0xcb, 0x56, 0x6f, 0x03, 0xca, 0x4e, 0x64, 0x36, 0x6e, 0xcb, 0xbe, 0x4c, 0x01, 0x7a, 0x07, + 0x48, 0x5b, 0x78, 0x22, 0x16, 0xfa, 0xfc, 0x2e, 0x89, 0x4f, 0xbb, 0x86, 0xcb, 0xc5, 0xb6, 0xe4, + 0x36, 0xe4, 0xf1, 0xe8, 0x4a, 0x2a, 0x95, 0xd6, 0xab, 0x69, 0xa6, 0x93, 0x39, 0xc1, 0xa4, 0x01, + 0x75, 0x4d, 0x50, 0x7d, 0xdc, 0x2f, 0xd8, 0xe0, 0x9c, 0x56, 0x36, 0x4b, 0xd9, 0xd3, 0x4b, 0x25, + 0x03, 0x44, 0x2f, 0xf5, 0xc0, 0xec, 0xf5, 0x65, 0x97, 0xa2, 0x5f, 0x68, 0x14, 0x8f, 0xc4, 0x3e, + 0x6a, 0x95, 0x8f, 0xfc, 0x5e, 0xbc, 0xe5, 0x29, 0x1e, 0x18, 0x1b, 0xcf, 0x50, 0x54, 0xb7, 0x9b, + 0x36, 0xc6, 0x96, 0x02, 0xbd, 0x07, 0xc5, 0x6e, 0xef, 0xb9, 0x18, 0x70, 0xf2, 0x16, 0x36, 0x6a, + 0x5f, 0x9c, 0x89, 0x48, 0xb7, 0xf9, 0xd5, 0xa9, 0xf4, 0x31, 0xa3, 0xa7, 0x3f, 0x58, 0x9a, 0xfd, + 0x02, 0x46, 0x45, 0xb9, 0x76, 0x54, 0xcf, 0xcf, 0x4c, 0x1c, 0xc4, 0x99, 0x56, 0x93, 0x0e, 0xd4, + 0x1c, 0x7f, 0x38, 0x8a, 0xdb, 0xe2, 0x6b, 0xd7, 0x77, 0x63, 0x37, 0xf0, 0xa3, 0x7a, 0x51, 0xba, + 0xdc, 0xc8, 0x2e, 0x3d, 0x61, 0xc1, 0x66, 0x5c, 0xe8, 0x77, 0x16, 0x5c, 0x9d, 0x02, 0x2f, 0xe0, + 0x95, 0x5b, 0xce, 0xeb, 0xdd, 0x64, 0x64, 0xda, 0xd2, 0xb0, 0xb1, 0x90, 0xcd, 0xe4, 0x04, 0xfd, + 0xc5, 0x82, 0x6b, 0xf3, 0x0c, 0xe6, 0xb2, 0x69, 0x00, 0x3c, 0x09, 0xdd, 0x01, 0x0f, 0xc7, 0x9f, + 0x88, 0xb1, 0xbe, 0x3d, 0x32, 0x08, 0xf9, 0x1c, 0xd6, 0xa7, 0x62, 0x7d, 0xd4, 0x53, 0x29, 0x52, + 0xa4, 0x6e, 0x2d, 0x24, 0xa5, 0xec, 0xd8, 0x02, 0x77, 0xfa, 0xa7, 0x05, 0xd7, 0xe7, 0xaa, 0xd2, + 0xee, 0xb3, 0xb2, 0x8d, 0x7e, 0x07, 0x6a, 0xcf, 0x70, 0x30, 0xb4, 0x45, 0x14, 0xbb, 0x3e, 0x47, + 0x4b, 0xdd, 0x9e, 0x33, 0x38, 0x71, 0xa0, 0x24, 0xb1, 0x3d, 0x3e, 0xd4, 0x34, 0xdf, 0xbe, 0x80, + 0xe6, 0x96, 0xb1, 0xd7, 0x73, 0xd3, 0x88, 0x48, 0x46, 0xce, 0x71, 0x73, 0x29, 0x48, 0x01, 0x27, + 0xe2, 0x84, 0xc3, 0xa5, 0xa6, 0x5a, 0x00, 0x1b, 0x66, 0x92, 0x4c, 0x30, 0x59, 0x7e, 0x26, 0x3f, + 0x00, 0x48, 0x4d, 0xf5, 0x71, 0x5f, 0xd2, 0x9f, 0x19, 0x63, 0xfa, 0x08, 0x36, 0xcc, 0x98, 0xbb, + 0xc4, 0x82, 0xa6, 0x5b, 0x72, 0x69, 0xb7, 0xd0, 0x0e, 0xd8, 0x4f, 0x99, 0x83, 0x57, 0x9d, 0x3c, + 0xad, 0xa6, 0x44, 0x5a, 0x42, 0x97, 0x47, 0x41, 0x14, 0x1b, 0x17, 0xfc, 0x46, 0xec, 0x49, 0x10, + 0xc6, 0x92, 0x71, 0x95, 0xc9, 0x6f, 0xfa, 0x1e, 0xe4, 0xf7, 0x83, 0xbe, 0x20, 0xab, 0x90, 0x73, + 0xda, 0x3a, 0x46, 0xce, 0x69, 0x93, 0x5b, 0x32, 0xbc, 0x9e, 0x21, 0xd5, 0x74, 0x73, 0x4f, 0x99, + 0xc3, 0x50, 0x43, 0x1f, 0x40, 0x0d, 0x1d, 0xbb, 0x31, 0x8f, 0x93, 0x11, 0xb6, 0x0e, 0x45, 0xc4, + 0x92, 0x40, 0x5a, 0x92, 0x17, 0x02, 0xda, 0x99, 0x21, 0x26, 0x05, 0xfa, 0xa3, 0x05, 0x60, 0x42, + 0x8c, 0x22, 0x42, 0x15, 0x13, 0xe9, 0x5a, 0x69, 0xad, 0xa6, 0x4b, 0x22, 0xca, 0x14, 0xcb, 0x77, + 0x32, 0xd7, 0xf0, 0xec, 0x7c, 0x4b, 0x54, 0x2c, 0x73, 0x59, 0x6f, 0x9a, 0x71, 0xa6, 0x0b, 0x55, + 0x4b, 0xed, 0x15, 0xae, 0x53, 0x86, 0x37, 0x40, 0x75, 0xd7, 0x1b, 0x45, 0xb1, 0x08, 0x35, 0x23, + 0x7c, 0x2e, 0x28, 0x20, 0xd9, 0x51, 0x0a, 0xcc, 0xdf, 0x14, 0x79, 0x03, 0x0a, 0xc8, 0xd4, 0x9c, + 0xc9, 0xe9, 0x6d, 0x28, 0x25, 0xed, 0x42, 0x61, 0xf1, 0x1c, 0x20, 0x90, 0x97, 0x8f, 0x43, 0x5d, + 0x3a, 0xf9, 0x2e, 0xac, 0x81, 0xbd, 0xe7, 0xaa, 0x5e, 0xb3, 0x19, 0x7e, 0x4a, 0x84, 0x9f, 0xc9, + 0xb3, 0x80, 0x08, 0xc7, 0x6b, 0x71, 0x4d, 0x35, 0x33, 0xce, 0xf1, 0x97, 0xb9, 0xc0, 0xcc, 0xfb, + 0xca, 0xce, 0xbc, 0xaf, 0xba, 0xb0, 0xa6, 0x1a, 0xf6, 0xff, 0x0c, 0xfa, 0x73, 0x0e, 0xd6, 0x98, + 0x88, 0xdc, 0x17, 0xc2, 0xf1, 0xa3, 0x38, 0x1c, 0x25, 0xc3, 0xe6, 0xe3, 0xe0, 0x50, 0xa7, 0xda, + 0x66, 0x4a, 0x48, 0xda, 0x22, 0xb7, 0xa4, 0x2d, 0xee, 0xe2, 0x4b, 0x3f, 0x08, 0xfb, 0x38, 0x74, + 0x82, 0x50, 0x17, 0x7a, 0xda, 0x34, 0x6b, 0x42, 0xee, 0xc2, 0x4a, 0x37, 0x18, 0x85, 0xbd, 0xe4, + 0x4a, 0x5a, 0x4f, 0xad, 0x15, 0x33, 0xa5, 0x66, 0xc6, 0x2c, 0xd3, 0x47, 0x85, 0xe5, 0x7d, 0x44, + 0xee, 0x4f, 0xf5, 0x91, 0x7c, 0x84, 0x57, 0x5a, 0xaf, 0xa5, 0x0e, 0x13, 0x6a, 0x36, 0x69, 0x4d, + 0xbf, 0xb7, 0xe0, 0x4a, 0x96, 0xc2, 0xbf, 0x3a, 0x18, 0x49, 0x45, 0x72, 0x73, 0x2b, 0x62, 0xcf, + 0xab, 0x48, 0x3e, 0xad, 0x48, 0xfa, 0x64, 0x2b, 0x64, 0x9e, 0x6c, 0xf4, 0x18, 0x6e, 0xcc, 0x94, + 0x69, 0x37, 0x18, 0x0c, 0xb1, 0x1f, 0xfe, 0x43, 0xb9, 0xae, 0x41, 0xa1, 0x13, 0x86, 0xba, 0x50, + 0x65, 0xa6, 0x04, 0xfa, 0x25, 0x5c, 0xef, 0x8a, 0x38, 0x53, 0x24, 0xd3, 0x6d, 0x4d, 0xb0, 0x1f, + 0x7b, 0xfd, 0x05, 0xdb, 0x47, 0x15, 0x5a, 0xec, 0x8b, 0xd3, 0x05, 0x6b, 0xa2, 0x8a, 0xee, 0x40, + 0xe9, 0x20, 0x18, 0x06, 0x5e, 0x70, 0x34, 0xbe, 0xe0, 0x58, 0xd7, 0x61, 0x45, 0x4d, 0x2d, 0xf5, + 0x28, 0x28, 0x33, 0x23, 0xee, 0xd4, 0x7e, 0x3d, 0x6f, 0x58, 0xbf, 0x9d, 0x37, 0xac, 0xdf, 0xcf, + 0x1b, 0xd6, 0x4f, 0x7f, 0x34, 0x5e, 0x39, 0x2c, 0xca, 0xff, 0xcf, 0x7b, 0xff, 0x04, 0x00, 0x00, + 0xff, 0xff, 0x03, 0x63, 0x93, 0xf4, 0x90, 0x0e, 0x00, 0x00, } diff --git a/internal/private.proto b/internal/private.proto index 4877707a2..1686b3be2 100644 --- a/internal/private.proto +++ b/internal/private.proto @@ -121,21 +121,26 @@ message URI { uint32 Port = 3; } +message Node { + string ID = 1; + URI URI = 2; +} + message NodeStateMessage { - URI URI = 1; + string NodeID = 1; string State = 2; } message NodeStatus { - URI URI = 1; + Node Node = 1; MaxSlices MaxSlices = 2; Schema Schema = 3; } message ClusterStatus { - string State = 1; - repeated URI NodeSet = 2; - string ClusterID = 3; + string ClusterID = 1; + string State = 2; + repeated Node Nodes = 3; } message Field { @@ -159,15 +164,15 @@ message DeleteViewMessage { message ResizeInstruction { int64 JobID = 1; - URI URI = 2; - URI Coordinator = 3; + Node Node = 2; + Node Coordinator = 3; repeated ResizeSource Sources = 4; Schema Schema = 5; ClusterStatus ClusterStatus = 6; } message ResizeSource { - URI URI = 1; + Node Node = 1; string Index = 2; string Frame = 3; string View = 4; @@ -176,17 +181,17 @@ message ResizeSource { message ResizeInstructionComplete { int64 JobID = 1; - URI URI = 2; + Node Node = 2; string Error = 3; } message SetCoordinatorMessage { - URI Old = 1; - URI New = 2; + Node Old = 1; + Node New = 2; } message Topology { - repeated URI NodeSet = 1; - string ClusterID = 2; + string ClusterID = 1; + repeated string NodeIDs = 2; } diff --git a/pilosa.go b/pilosa.go index af4186513..6e7777804 100644 --- a/pilosa.go +++ b/pilosa.go @@ -162,8 +162,8 @@ func StringInSlice(a string, list []string) bool { return false } -// URISlicesAreEqual determines if two string slices are equal. -func URISlicesAreEqual(a, b []URI) bool { +// StringSlicesAreEqual determines if two string slices are equal. +func StringSlicesAreEqual(a, b []string) bool { if a == nil && b == nil { return true diff --git a/server.go b/server.go index 6b7d49cc5..7652a6c5b 100644 --- a/server.go +++ b/server.go @@ -58,9 +58,6 @@ type Server struct { wg sync.WaitGroup closing chan struct{} - // Unique name identifying the server. - Name string - // Data storage and HTTP interface. Holder *Holder Handler *Handler @@ -70,8 +67,8 @@ type Server struct { RemoteClient *http.Client // Cluster configuration. - // Host is replaced with actual host after opening if port is ":0". Network string + NodeID string URI URI Cluster *Cluster diagnostics *diagnostics.Diagnostics @@ -128,16 +125,15 @@ func (s *Server) Open() error { } } - // Set Cluster URI. - s.Cluster.URI = s.URI + // Get or create NodeID. + s.NodeID = s.LoadNodeID() - // Find the Node ID and append that tag to stats. - for i, n := range s.Cluster.Nodes { - if n.URI == s.URI { - s.Holder.Stats = s.Holder.Stats.WithTags(fmt.Sprintf("NodeID:%d", i)) - break - } - } + // Set Cluster Node. + node := &Node{ID: s.NodeID, URI: s.URI} + s.Cluster.Node = node + + // Append the NodeID tag to stats. + s.Holder.Stats = s.Holder.Stats.WithTags(fmt.Sprintf("NodeID:%s", s.NodeID)) // Peek at the holder to determine if there is data on disk. // Don't actually load the data until after the Cluster @@ -151,7 +147,7 @@ func (s *Server) Open() error { // Create executor for executing queries. e := NewExecutor(s.RemoteClient) e.Holder = s.Holder - e.URI = s.URI + e.Node = node e.Cluster = s.Cluster e.MaxWritesPerRequest = s.MaxWritesPerRequest @@ -163,7 +159,7 @@ func (s *Server) Open() error { s.Handler.Broadcaster = s.Broadcaster s.Handler.BroadcastHandler = s s.Handler.StatusHandler = s - s.Handler.URI = s.URI + s.Handler.Node = node s.Handler.Cluster = s.Cluster s.Handler.Executor = e s.Handler.LogOutput = s.LogOutput @@ -211,11 +207,6 @@ func (s *Server) Open() error { // buffered channel. s.Cluster.ListenForJoins() - // Load NodeID. - if err := s.Holder.loadNodeID(); err != nil { - s.Logger().Println(err) - } - // Start background monitoring. s.wg.Add(3) go func() { defer s.wg.Done(); s.monitorAntiEntropy() }() @@ -259,11 +250,6 @@ func (s *Server) OpenListener() error { s.URI.SetPort(uint16(s.ln.Addr().(*net.TCPAddr).Port)) } - // If name is not provided in the config, default to the URI. - if s.Name == "" { - s.Name = s.URI.String() - } - return nil } @@ -286,6 +272,20 @@ func (s *Server) Close() error { return nil } +// LoadNodeID gets NodeID from disk, or creates a new value. +// If server.NodeID is already set, a new ID is not created. +func (s *Server) LoadNodeID() string { + if s.NodeID != "" { + return s.NodeID + } + nodeID, err := s.Holder.loadNodeID() + if err != nil { + s.Logger().Printf("loading NodeID: %v", err) + return s.NodeID + } + return nodeID +} + // Addr returns the address of the listener. func (s *Server) Addr() net.Addr { if s.ln == nil { @@ -336,7 +336,7 @@ func (s *Server) monitorAntiEntropy() { // Initialize syncer with local holder and remote client. var syncer HolderSyncer syncer.Holder = s.Holder - syncer.URI = s.URI + syncer.Node = s.Cluster.Node syncer.Cluster = s.Cluster syncer.Closing = s.closing syncer.RemoteClient = s.RemoteClient @@ -442,9 +442,9 @@ func (s *Server) ReceiveMessage(pb proto.Message) error { return err } case *internal.SetCoordinatorMessage: - s.Cluster.SetCoordinator(DecodeURI(obj.Old), DecodeURI(obj.New)) + s.Cluster.SetCoordinator(DecodeNode(obj.Old), DecodeNode(obj.New)) case *internal.NodeStateMessage: - err := s.Cluster.ReceiveNodeState(DecodeURI(obj.URI), obj.State) + err := s.Cluster.ReceiveNodeState(obj.NodeID, obj.State) if err != nil { return err } @@ -503,7 +503,7 @@ func (s *Server) LocalStatus() (proto.Message, error) { } ns := internal.NodeStatus{ - URI: encodeURI(s.URI), + Node: EncodeNode(s.Cluster.Node), MaxSlices: s.Holder.EncodeMaxSlices(), Schema: s.Holder.EncodeSchema(), } @@ -538,7 +538,7 @@ func (s *Server) HandleRemoteStatus(pb proto.Message) error { func (s *Server) mergeRemoteStatus(ns *internal.NodeStatus) error { // Ignore status updates from self. - if s.URI == decodeURI(ns.URI) { + if s.NodeID == DecodeNode(ns.Node).ID { return nil } @@ -594,10 +594,10 @@ func (s *Server) monitorDiagnostics() { s.diagnostics.SetInterval(s.DiagnosticInterval) s.diagnostics.Open() s.diagnostics.Set("Host", s.URI.host) - s.diagnostics.Set("Cluster", strings.Join(NodeSet(s.Cluster.NodeSet()).ToStrings(), ",")) + s.diagnostics.Set("Cluster", strings.Join(s.Cluster.NodeIDs(), ",")) s.diagnostics.Set("NumNodes", len(s.Cluster.Nodes)) s.diagnostics.Set("NumCPU", runtime.NumCPU()) - s.diagnostics.Set("NodeID", s.Holder.NodeID) + s.diagnostics.Set("NodeID", s.NodeID) s.diagnostics.Set("ClusterID", s.Cluster.ID) s.diagnostics.EnrichWithOSInfo() diff --git a/server/cluster_test.go b/server/cluster_test.go index 98b723335..f8789f169 100644 --- a/server/cluster_test.go +++ b/server/cluster_test.go @@ -38,8 +38,8 @@ func TestMain_SendReceiveMessage(t *testing.T) { // Update cluster config m0.Server.Cluster.Nodes = []*pilosa.Node{ - {URI: m0.Server.URI}, - {URI: m1.Server.URI}, + {ID: m0.Server.NodeID, URI: m0.Server.URI}, + {ID: m1.Server.NodeID, URI: m1.Server.URI}, } m1.Server.Cluster.Nodes = m0.Server.Cluster.Nodes @@ -50,7 +50,7 @@ func TestMain_SendReceiveMessage(t *testing.T) { m0.Config.Gossip.Seed = "" m0.Server.Cluster.Coordinator = m0.Server.URI - m0.Server.Cluster.Topology = &pilosa.Topology{NodeSet: []pilosa.URI{m0.Server.URI, m1.Server.URI}} + m0.Server.Cluster.Topology = &pilosa.Topology{NodeIDs: []string{m0.Server.NodeID, m1.Server.NodeID}} m0.Server.Cluster.EventReceiver = gossip.NewGossipEventReceiver() gossipMemberSet0, err := gossip.NewGossipMemberSet(m0.Server.URI.HostPort(), m0.Config, m0.Server) if err != nil { diff --git a/server/server.go b/server/server.go index d238d1c2f..5b2b2010d 100644 --- a/server/server.go +++ b/server/server.go @@ -128,11 +128,6 @@ func (m *Command) SetupServer() error { } m.Server.URI = *uri - // If using a dynamically allocated port, server.Name will get set later. - if m.Config.Bind != "localhost:0" { - m.Server.Name = m.Server.URI.String() - } - cluster := pilosa.NewCluster() cluster.ReplicaN = m.Config.Cluster.ReplicaN cluster.Holder = m.Server.Holder @@ -218,7 +213,6 @@ func (m *Command) SetupServer() error { func (m *Command) SetupNetworking() error { switch m.Config.Cluster.Type { case pilosa.ClusterGossip: - // Set internal port (string). gossipPortStr := pilosa.DefaultGossipPort // Config.GossipPort is deprecated, so Config.Gossip.Port has priority @@ -245,11 +239,10 @@ func (m *Command) SetupNetworking() error { } } + m.Server.NodeID = m.Server.LoadNodeID() + m.Server.Cluster.EventReceiver = gossip.NewGossipEventReceiver() - if m.Server.Name == "" { - return fmt.Errorf("must provide a valid name for gossip membership") - } - gossipMemberSet, err := gossip.NewGossipMemberSetWithTransport(m.Server.Name, m.Config, transport, m.Server) + gossipMemberSet, err := gossip.NewGossipMemberSetWithTransport(m.Server.NodeID, m.Config, transport, m.Server) if err != nil { return err } diff --git a/test/cluster.go b/test/cluster.go index ebe48fd35..55f5ad074 100644 --- a/test/cluster.go +++ b/test/cluster.go @@ -6,7 +6,6 @@ import ( "fmt" "io/ioutil" "path/filepath" - "sort" "sync" "time" @@ -30,10 +29,14 @@ func NewCluster(n int) *pilosa.Cluster { for i := 0; i < n; i++ { c.Nodes = append(c.Nodes, &pilosa.Node{ + ID: fmt.Sprintf("node%d", i), URI: NewURI("http", fmt.Sprintf("host%d", i), uint16(0)), }) } + c.Node = c.Nodes[0] + c.Coordinator = c.Nodes[0].URI + return c } @@ -84,7 +87,7 @@ type TestCluster struct { } type commonClusterSettings struct { - NodeSet pilosa.NodeSet + Nodes []*pilosa.Node } func (t *TestCluster) CreateIndex(name string) error { @@ -115,7 +118,7 @@ func (t *TestCluster) SetBit(index, frame, view string, rowID, colID uint64, x * nodes := c0.FragmentNodes(index, slice) for _, node := range nodes { - c := t.clusterByURI(node.URI) + c := t.clusterByID(node.ID) if c == nil { continue } @@ -139,7 +142,7 @@ func (t *TestCluster) SetFieldValue(index, frame string, columnID uint64, name s nodes := c0.FragmentNodes(index, slice) for _, node := range nodes { - c := t.clusterByURI(node.URI) + c := t.clusterByID(node.ID) if c == nil { continue } @@ -156,9 +159,9 @@ func (t *TestCluster) SetFieldValue(index, frame string, columnID uint64, name s return nil } -func (t *TestCluster) clusterByURI(uri pilosa.URI) *pilosa.Cluster { +func (t *TestCluster) clusterByID(id string) *pilosa.Cluster { for _, c := range t.Clusters { - if c.URI == uri { + if c.Node.ID == id { return c } } @@ -179,7 +182,7 @@ func (t *TestCluster) AddNode(saveTopology bool) error { coord := t.Clusters[0] ev := &pilosa.NodeEvent{ Event: pilosa.NodeJoin, - URI: c.URI, + Node: c.Node, } if err := coord.ReceiveEvent(ev); err != nil { @@ -211,11 +214,20 @@ func (t *TestCluster) WriteTopology(path string, top *pilosa.Topology) error { func (t *TestCluster) addCluster(i int, saveTopology bool) (*pilosa.Cluster, error) { + id := fmt.Sprintf("node%d", i) uri := NewURI("http", fmt.Sprintf("host%d", i), uint16(0)) + node := &pilosa.Node{ + ID: id, + URI: uri, + } + // add URI to common - t.common.NodeSet = append(t.common.NodeSet, uri) - sort.Sort(t.common.NodeSet) + //t.common.NodeIDs = append(t.common.NodeIDs, id) + //sort.Sort(t.common.NodeIDs) + + // add node to common + t.common.Nodes = append(t.common.Nodes, node) // create node-specific temp directory path, err := ioutil.TempDir("", fmt.Sprintf("pilosa-cluster-node-%d-", i)) @@ -235,14 +247,14 @@ func (t *TestCluster) addCluster(i int, saveTopology bool) (*pilosa.Cluster, err c.Topology = pilosa.NewTopology() c.Holder = h c.MemberSet = pilosa.NewStaticMemberSet() - c.URI = uri - c.Coordinator = t.common.NodeSet[0] // the first node is the coordinator + c.Node = node + c.Coordinator = t.common.Nodes[0].URI // the first node is the coordinator c.Broadcaster = t // add nodes if saveTopology { - for _, u := range t.common.NodeSet { - c.AddNode(u) + for _, n := range t.common.Nodes { + c.AddNode(n) } } @@ -344,7 +356,7 @@ func (t *TestCluster) SendTo(to *pilosa.Node, pb proto.Message) error { return err } case *internal.ResizeInstructionComplete: - coord := t.clusterByURI(to.URI) + coord := t.clusterByID(to.ID) go coord.MarkResizeInstructionComplete(obj) } return nil @@ -356,7 +368,7 @@ func (t *TestCluster) FollowResizeInstruction(instr *internal.ResizeInstruction) // Prepare the return message. complete := &internal.ResizeInstructionComplete{ JobID: instr.JobID, - URI: instr.URI, + Node: instr.Node, Error: "", } @@ -365,8 +377,8 @@ func (t *TestCluster) FollowResizeInstruction(instr *internal.ResizeInstruction) // figure out which node it was meant for, then call the operation on that cluster // basically need to mimic this: client.RetrieveSliceFromURI(context.Background(), src.Index, src.Frame, src.View, src.Slice, srcURI) - instrURI := pilosa.DecodeURI(instr.URI) - destCluster := t.clusterByURI(instrURI) + instrNode := pilosa.DecodeNode(instr.Node) + destCluster := t.clusterByID(instrNode.ID) // Sync the schema received in the resize instruction. if err := destCluster.Holder.ApplySchema(instr.Schema); err != nil { @@ -374,8 +386,8 @@ func (t *TestCluster) FollowResizeInstruction(instr *internal.ResizeInstruction) } for _, src := range instr.Sources { - srcURI := pilosa.DecodeURI(src.URI) - srcCluster := t.clusterByURI(srcURI) + srcNode := pilosa.DecodeNode(src.Node) + srcCluster := t.clusterByID(srcNode.ID) srcFragment := srcCluster.Holder.Fragment(src.Index, src.Frame, src.View, src.Slice) destFragment := destCluster.Holder.Fragment(src.Index, src.Frame, src.View, src.Slice) @@ -414,9 +426,7 @@ func (t *TestCluster) FollowResizeInstruction(instr *internal.ResizeInstruction) complete.Error = err.Error() } - node := &pilosa.Node{ - URI: pilosa.DecodeURI(instr.Coordinator), - } + node := pilosa.DecodeNode(instr.Coordinator) if err := t.SendTo(node, complete); err != nil { return err } diff --git a/test/executor.go b/test/executor.go index 5d6872626..85445719d 100644 --- a/test/executor.go +++ b/test/executor.go @@ -26,7 +26,7 @@ func NewExecutor(holder *pilosa.Holder, cluster *pilosa.Cluster) *Executor { e := &Executor{Executor: executor} e.Holder = holder e.Cluster = cluster - e.URI = cluster.Nodes[0].URI + e.Node = cluster.Nodes[0] return e } diff --git a/test/handler.go b/test/handler.go index 6c6703f84..4859443c6 100644 --- a/test/handler.go +++ b/test/handler.go @@ -67,7 +67,6 @@ func NewServer() *Server { if err != nil { panic(err) } - s.Handler.URI = *uri // Handler test messages can no-op. s.Handler.Broadcaster = pilosa.NopBroadcaster @@ -75,6 +74,8 @@ func NewServer() *Server { s.Handler.Cluster = NewCluster(1) s.Handler.Cluster.Nodes[0].URI = *uri + s.Handler.Node = s.Handler.Cluster.Nodes[0] + return s } @@ -85,10 +86,16 @@ func (s *Server) LocalStatus() (proto.Message, error) { // ClusterStatus exists so that test.Server implements StatusHandler. func (s *Server) ClusterStatus() (proto.Message, error) { + id := "test-node" uri := pilosa.DefaultURI() + node := &pilosa.Node{ + ID: id, + URI: *uri, + } return &internal.ClusterStatus{ - State: pilosa.ClusterStateNormal, - NodeSet: []*internal.URI{uri.Encode()}, + ClusterID: "", + State: pilosa.ClusterStateNormal, + Nodes: pilosa.EncodeNodes([]*pilosa.Node{node}), }, nil } diff --git a/uri.go b/uri.go index 388650044..beb5060b5 100644 --- a/uri.go +++ b/uri.go @@ -57,6 +57,16 @@ func DefaultURI() *URI { } } +type URIs []URI + +func (u URIs) HostPortStrings() []string { + s := make([]string, len(u)) + for i, a := range u { + s[i] = a.HostPort() + } + return s +} + // NewURIFromHostPort returns a URI with specified host and port. func NewURIFromHostPort(host string, port uint16) (*URI, error) { uri := DefaultURI() From 86dbbbf393fb6a4f3202184d7235c6dbfc70cf63 Mon Sep 17 00:00:00 2001 From: Travis Turner Date: Fri, 2 Feb 2018 15:51:24 -0600 Subject: [PATCH 2/3] don't require oldNode in SetCoordinator() --- cluster.go | 14 +-- cluster_test.go | 4 +- handler.go | 9 +- internal/private.pb.go | 223 ++++++++++++++++------------------------- internal/private.proto | 3 +- server.go | 2 +- 6 files changed, 93 insertions(+), 162 deletions(-) diff --git a/cluster.go b/cluster.go index 1ed810ea0..d531c90d6 100644 --- a/cluster.go +++ b/cluster.go @@ -297,22 +297,16 @@ func (c *Cluster) IsCoordinator() bool { return c.Static || c.Coordinator == c.Node.URI } -// SetCoordinator updates the Coordinator to new if it is -// currently old. Returns true if the Coordinator changed. -func (c *Cluster) SetCoordinator(o, n *Node) bool { - // Get old node. - oldNode := c.nodeByID(o.ID) - if oldNode == nil { - return false - } - +// SetCoordinator updates the Coordinator to n. +// Returns true if the Coordinator changed. +func (c *Cluster) SetCoordinator(n *Node) bool { // Get new node. newNode := c.nodeByID(n.ID) if newNode == nil { return false } - if c.Coordinator == oldNode.URI && oldNode != newNode { + if c.Coordinator != newNode.URI { c.Coordinator = newNode.URI return true } diff --git a/cluster_test.go b/cluster_test.go index 9bcacac9a..5a5fa4de4 100644 --- a/cluster_test.go +++ b/cluster_test.go @@ -517,14 +517,14 @@ func TestCluster_SetCoordinator(t *testing.T) { newNode := c.Nodes[1] // Set coordinator to the same value. - if set := c.SetCoordinator(oldNode, oldNode); set { + if c.SetCoordinator(oldNode) { t.Errorf("did not expect coordinator to change") } else if c.Coordinator != oldNode.URI { t.Errorf("expected coordinator: %s, but got: %s", c.Coordinator, oldNode.URI) } // Set coordinator to a new value. - if set := c.SetCoordinator(oldNode, newNode); !set { + if !c.SetCoordinator(newNode) { t.Errorf("expected coordinator to change") } else if c.Coordinator != newNode.URI { t.Errorf("expected coordinator: %s, but got: %s", c.Coordinator, newNode.URI) diff --git a/handler.go b/handler.go index a12e7b391..dd438e977 100644 --- a/handler.go +++ b/handler.go @@ -1964,11 +1964,6 @@ func (h *Handler) handlePostClusterResizeSetCoordinator(w http.ResponseWriter, r return } - oldNode := h.Cluster.nodeByURI(h.Cluster.Coordinator) - if oldNode == nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } newNode := h.Cluster.nodeByID(req.ID) if newNode == nil { http.Error(w, err.Error(), http.StatusBadRequest) @@ -1979,7 +1974,6 @@ func (h *Handler) handlePostClusterResizeSetCoordinator(w http.ResponseWriter, r // Send the set-coordinator message to all nodes. err := h.Broadcaster.SendSync( &internal.SetCoordinatorMessage{ - Old: EncodeNode(oldNode), New: EncodeNode(newNode), }) if err != nil { @@ -1987,7 +1981,7 @@ func (h *Handler) handlePostClusterResizeSetCoordinator(w http.ResponseWriter, r } // Set Coordinator on local node. - _ = h.Cluster.SetCoordinator(oldNode, newNode) + _ = h.Cluster.SetCoordinator(newNode) return nil }(); err != nil { @@ -1997,7 +1991,6 @@ func (h *Handler) handlePostClusterResizeSetCoordinator(w http.ResponseWriter, r // Encode response. if err := json.NewEncoder(w).Encode(setCoordinatorResponse{ - Old: oldNode, New: newNode, }); err != nil { h.logger().Printf("response encoding error: %s", err) diff --git a/internal/private.pb.go b/internal/private.pb.go index ae6247bb6..b584a10a9 100644 --- a/internal/private.pb.go +++ b/internal/private.pb.go @@ -1029,8 +1029,7 @@ func (m *ResizeInstructionComplete) GetError() string { } type SetCoordinatorMessage struct { - Old *Node `protobuf:"bytes,1,opt,name=Old" json:"Old,omitempty"` - New *Node `protobuf:"bytes,2,opt,name=New" json:"New,omitempty"` + New *Node `protobuf:"bytes,1,opt,name=New" json:"New,omitempty"` } func (m *SetCoordinatorMessage) Reset() { *m = SetCoordinatorMessage{} } @@ -1038,13 +1037,6 @@ func (m *SetCoordinatorMessage) String() string { return proto.Compac func (*SetCoordinatorMessage) ProtoMessage() {} func (*SetCoordinatorMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{31} } -func (m *SetCoordinatorMessage) GetOld() *Node { - if m != nil { - return m.Old - } - return nil -} - func (m *SetCoordinatorMessage) GetNew() *Node { if m != nil { return m.New @@ -2405,26 +2397,16 @@ func (m *SetCoordinatorMessage) MarshalTo(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.Old != nil { + if m.New != nil { dAtA[i] = 0xa i++ - i = encodeVarintPrivate(dAtA, i, uint64(m.Old.Size())) - n21, err := m.Old.MarshalTo(dAtA[i:]) + i = encodeVarintPrivate(dAtA, i, uint64(m.New.Size())) + n21, err := m.New.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n21 } - if m.New != nil { - dAtA[i] = 0x12 - i++ - i = encodeVarintPrivate(dAtA, i, uint64(m.New.Size())) - n22, err := m.New.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n22 - } return i, nil } @@ -3065,10 +3047,6 @@ func (m *ResizeInstructionComplete) Size() (n int) { func (m *SetCoordinatorMessage) Size() (n int) { var l int _ = l - if m.Old != nil { - l = m.Old.Size() - n += 1 + l + sovPrivate(uint64(l)) - } if m.New != nil { l = m.New.Size() n += 1 + l + sovPrivate(uint64(l)) @@ -7524,39 +7502,6 @@ func (m *SetCoordinatorMessage) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Old", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPrivate - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthPrivate - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Old == nil { - m.Old = &Node{} - } - if err := m.Old.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field New", wireType) } @@ -7826,84 +7771,84 @@ var ( func init() { proto.RegisterFile("private.proto", fileDescriptorPrivate) } var fileDescriptorPrivate = []byte{ - // 1258 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x5b, 0x6f, 0x1b, 0x45, - 0x14, 0x66, 0xbd, 0xb6, 0x63, 0x1f, 0xd7, 0xa9, 0x33, 0xb4, 0xc1, 0xad, 0x22, 0xd7, 0x8c, 0x10, - 0x0d, 0x95, 0x88, 0x8a, 0x2b, 0x71, 0x09, 0xaa, 0x54, 0x12, 0xbb, 0xea, 0x02, 0x49, 0xcb, 0x38, - 0x2d, 0x12, 0x48, 0x48, 0x13, 0x7b, 0x48, 0x57, 0x59, 0xef, 0x9a, 0xdd, 0x75, 0x12, 0xf7, 0x81, - 0x47, 0x84, 0x84, 0x78, 0x47, 0xbc, 0xf2, 0x67, 0x78, 0xe4, 0x27, 0xa0, 0xf0, 0x23, 0x90, 0x78, - 0x01, 0x9d, 0xb9, 0xec, 0xae, 0xaf, 0x21, 0x85, 0xb7, 0x3d, 0xdf, 0xb9, 0xcc, 0x37, 0xe7, 0x9c, - 0x39, 0x33, 0x0b, 0xd5, 0x61, 0xe8, 0x9e, 0xf0, 0x58, 0x6c, 0x0d, 0xc3, 0x20, 0x0e, 0x48, 0xc9, - 0xf5, 0x63, 0x11, 0xfa, 0xdc, 0xa3, 0x8f, 0xa1, 0xec, 0xf8, 0x7d, 0x71, 0xb6, 0x27, 0x62, 0x4e, - 0x9a, 0x50, 0xd9, 0x0d, 0xbc, 0xd1, 0xc0, 0xff, 0x94, 0x1f, 0x0a, 0xaf, 0x6e, 0x35, 0xad, 0xcd, - 0x32, 0xcb, 0x42, 0x68, 0x71, 0xe0, 0x0e, 0xc4, 0x67, 0x23, 0xee, 0xc7, 0xa3, 0x41, 0x3d, 0xa7, - 0x2c, 0x32, 0x10, 0xfd, 0xcb, 0x82, 0xf2, 0xc3, 0x90, 0x0f, 0x84, 0x8c, 0x78, 0x13, 0x4a, 0x2c, - 0x38, 0xcd, 0x86, 0x4b, 0x64, 0xf2, 0x26, 0xac, 0x3a, 0xfe, 0x89, 0x08, 0x23, 0xd1, 0xf1, 0xf9, - 0xa1, 0x27, 0xfa, 0x32, 0x5c, 0x89, 0x4d, 0xa1, 0x64, 0x03, 0xca, 0xbb, 0xbc, 0xf7, 0x5c, 0x1c, - 0x8c, 0x87, 0xa2, 0x6e, 0xcb, 0x20, 0x29, 0x90, 0x68, 0xbb, 0xee, 0x0b, 0x51, 0xcf, 0x37, 0xad, - 0xcd, 0x2a, 0x4b, 0x81, 0x69, 0xbe, 0x85, 0x19, 0xbe, 0x84, 0xc2, 0x15, 0xc6, 0xfd, 0xa3, 0x84, - 0x43, 0x51, 0x72, 0x98, 0xc0, 0xc8, 0x6d, 0x28, 0x3e, 0x74, 0x85, 0xd7, 0x8f, 0xea, 0x2b, 0x4d, - 0x7b, 0xb3, 0xd2, 0xba, 0xba, 0x65, 0xf2, 0xb7, 0x25, 0x71, 0xa6, 0xd5, 0x94, 0xc2, 0xaa, 0x33, - 0x18, 0x06, 0x61, 0xcc, 0x44, 0x34, 0x0c, 0xfc, 0x48, 0x90, 0x1a, 0xd8, 0x9d, 0x30, 0xd4, 0x7b, - 0xc7, 0x4f, 0xfa, 0x2d, 0xd4, 0x76, 0xbc, 0xa0, 0x77, 0xdc, 0xe6, 0x31, 0x67, 0xe2, 0x9b, 0x91, - 0x88, 0x62, 0x72, 0x0d, 0x0a, 0xb2, 0x0a, 0xda, 0x4e, 0x09, 0x88, 0xca, 0x4c, 0xea, 0x34, 0x2b, - 0x01, 0x51, 0xe9, 0x2f, 0x53, 0x91, 0x67, 0x4a, 0x40, 0xb4, 0xeb, 0xb9, 0x3d, 0x95, 0x82, 0x3c, - 0x53, 0x02, 0x21, 0x90, 0x7f, 0xe6, 0x8a, 0x53, 0xbd, 0x6f, 0xf9, 0x4d, 0x1d, 0x58, 0xcb, 0xac, - 0xaf, 0x69, 0xae, 0x43, 0x91, 0x05, 0xa7, 0x4e, 0x3b, 0xaa, 0x5b, 0x4d, 0x7b, 0x33, 0xcf, 0xb4, - 0x24, 0xb3, 0x2b, 0xcb, 0x8f, 0xaa, 0x9c, 0x54, 0xa5, 0x00, 0xbd, 0x01, 0x05, 0x99, 0x6a, 0xdc, - 0x65, 0xea, 0x8b, 0x9f, 0xf4, 0x6f, 0x0b, 0xca, 0x7b, 0xfc, 0x4c, 0xd2, 0x88, 0xc8, 0x7d, 0x28, - 0x75, 0x63, 0xee, 0xf7, 0x79, 0xd8, 0x97, 0x46, 0x95, 0xd6, 0xeb, 0x69, 0x0a, 0x13, 0xb3, 0x2d, - 0x63, 0xd3, 0xf1, 0xe3, 0x70, 0xcc, 0x12, 0x17, 0xb2, 0x0d, 0x2b, 0xba, 0x27, 0x24, 0x87, 0x4a, - 0xab, 0x39, 0xcf, 0x3b, 0x69, 0x1b, 0x74, 0x36, 0x0e, 0x37, 0x3f, 0x84, 0xea, 0x44, 0x58, 0xe4, - 0x7a, 0x2c, 0xc6, 0xa6, 0x22, 0xc7, 0x62, 0x8c, 0xb9, 0x3b, 0xe1, 0xde, 0x48, 0xe5, 0x39, 0xcf, - 0x94, 0xb0, 0x9d, 0x7b, 0xdf, 0xba, 0xb9, 0x0d, 0x57, 0xb2, 0x51, 0x2f, 0xe3, 0x4b, 0xbf, 0x02, - 0xb2, 0x1b, 0x0a, 0x1e, 0x0b, 0x49, 0x6f, 0x4f, 0x44, 0x11, 0x3f, 0x12, 0x8b, 0x2b, 0xad, 0xaa, - 0x97, 0xcb, 0x56, 0x6f, 0x03, 0xca, 0x4e, 0x64, 0x36, 0x6e, 0xcb, 0xbe, 0x4c, 0x01, 0x7a, 0x07, - 0x48, 0x5b, 0x78, 0x22, 0x16, 0xfa, 0xfc, 0x2e, 0x89, 0x4f, 0xbb, 0x86, 0xcb, 0xc5, 0xb6, 0xe4, - 0x36, 0xe4, 0xf1, 0xe8, 0x4a, 0x2a, 0x95, 0xd6, 0xab, 0x69, 0xa6, 0x93, 0x39, 0xc1, 0xa4, 0x01, - 0x75, 0x4d, 0x50, 0x7d, 0xdc, 0x2f, 0xd8, 0xe0, 0x9c, 0x56, 0x36, 0x4b, 0xd9, 0xd3, 0x4b, 0x25, - 0x03, 0x44, 0x2f, 0xf5, 0xc0, 0xec, 0xf5, 0x65, 0x97, 0xa2, 0x5f, 0x68, 0x14, 0x8f, 0xc4, 0x3e, - 0x6a, 0x95, 0x8f, 0xfc, 0x5e, 0xbc, 0xe5, 0x29, 0x1e, 0x18, 0x1b, 0xcf, 0x50, 0x54, 0xb7, 0x9b, - 0x36, 0xc6, 0x96, 0x02, 0xbd, 0x07, 0xc5, 0x6e, 0xef, 0xb9, 0x18, 0x70, 0xf2, 0x16, 0x36, 0x6a, - 0x5f, 0x9c, 0x89, 0x48, 0xb7, 0xf9, 0xd5, 0xa9, 0xf4, 0x31, 0xa3, 0xa7, 0x3f, 0x58, 0x9a, 0xfd, - 0x02, 0x46, 0x45, 0xb9, 0x76, 0x54, 0xcf, 0xcf, 0x4c, 0x1c, 0xc4, 0x99, 0x56, 0x93, 0x0e, 0xd4, - 0x1c, 0x7f, 0x38, 0x8a, 0xdb, 0xe2, 0x6b, 0xd7, 0x77, 0x63, 0x37, 0xf0, 0xa3, 0x7a, 0x51, 0xba, - 0xdc, 0xc8, 0x2e, 0x3d, 0x61, 0xc1, 0x66, 0x5c, 0xe8, 0x77, 0x16, 0x5c, 0x9d, 0x02, 0x2f, 0xe0, - 0x95, 0x5b, 0xce, 0xeb, 0xdd, 0x64, 0x64, 0xda, 0xd2, 0xb0, 0xb1, 0x90, 0xcd, 0xe4, 0x04, 0xfd, - 0xc5, 0x82, 0x6b, 0xf3, 0x0c, 0xe6, 0xb2, 0x69, 0x00, 0x3c, 0x09, 0xdd, 0x01, 0x0f, 0xc7, 0x9f, - 0x88, 0xb1, 0xbe, 0x3d, 0x32, 0x08, 0xf9, 0x1c, 0xd6, 0xa7, 0x62, 0x7d, 0xd4, 0x53, 0x29, 0x52, - 0xa4, 0x6e, 0x2d, 0x24, 0xa5, 0xec, 0xd8, 0x02, 0x77, 0xfa, 0xa7, 0x05, 0xd7, 0xe7, 0xaa, 0xd2, - 0xee, 0xb3, 0xb2, 0x8d, 0x7e, 0x07, 0x6a, 0xcf, 0x70, 0x30, 0xb4, 0x45, 0x14, 0xbb, 0x3e, 0x47, - 0x4b, 0xdd, 0x9e, 0x33, 0x38, 0x71, 0xa0, 0x24, 0xb1, 0x3d, 0x3e, 0xd4, 0x34, 0xdf, 0xbe, 0x80, - 0xe6, 0x96, 0xb1, 0xd7, 0x73, 0xd3, 0x88, 0x48, 0x46, 0xce, 0x71, 0x73, 0x29, 0x48, 0x01, 0x27, - 0xe2, 0x84, 0xc3, 0xa5, 0xa6, 0x5a, 0x00, 0x1b, 0x66, 0x92, 0x4c, 0x30, 0x59, 0x7e, 0x26, 0x3f, - 0x00, 0x48, 0x4d, 0xf5, 0x71, 0x5f, 0xd2, 0x9f, 0x19, 0x63, 0xfa, 0x08, 0x36, 0xcc, 0x98, 0xbb, - 0xc4, 0x82, 0xa6, 0x5b, 0x72, 0x69, 0xb7, 0xd0, 0x0e, 0xd8, 0x4f, 0x99, 0x83, 0x57, 0x9d, 0x3c, - 0xad, 0xa6, 0x44, 0x5a, 0x42, 0x97, 0x47, 0x41, 0x14, 0x1b, 0x17, 0xfc, 0x46, 0xec, 0x49, 0x10, - 0xc6, 0x92, 0x71, 0x95, 0xc9, 0x6f, 0xfa, 0x1e, 0xe4, 0xf7, 0x83, 0xbe, 0x20, 0xab, 0x90, 0x73, - 0xda, 0x3a, 0x46, 0xce, 0x69, 0x93, 0x5b, 0x32, 0xbc, 0x9e, 0x21, 0xd5, 0x74, 0x73, 0x4f, 0x99, - 0xc3, 0x50, 0x43, 0x1f, 0x40, 0x0d, 0x1d, 0xbb, 0x31, 0x8f, 0x93, 0x11, 0xb6, 0x0e, 0x45, 0xc4, - 0x92, 0x40, 0x5a, 0x92, 0x17, 0x02, 0xda, 0x99, 0x21, 0x26, 0x05, 0xfa, 0xa3, 0x05, 0x60, 0x42, - 0x8c, 0x22, 0x42, 0x15, 0x13, 0xe9, 0x5a, 0x69, 0xad, 0xa6, 0x4b, 0x22, 0xca, 0x14, 0xcb, 0x77, - 0x32, 0xd7, 0xf0, 0xec, 0x7c, 0x4b, 0x54, 0x2c, 0x73, 0x59, 0x6f, 0x9a, 0x71, 0xa6, 0x0b, 0x55, - 0x4b, 0xed, 0x15, 0xae, 0x53, 0x86, 0x37, 0x40, 0x75, 0xd7, 0x1b, 0x45, 0xb1, 0x08, 0x35, 0x23, - 0x7c, 0x2e, 0x28, 0x20, 0xd9, 0x51, 0x0a, 0xcc, 0xdf, 0x14, 0x79, 0x03, 0x0a, 0xc8, 0xd4, 0x9c, - 0xc9, 0xe9, 0x6d, 0x28, 0x25, 0xed, 0x42, 0x61, 0xf1, 0x1c, 0x20, 0x90, 0x97, 0x8f, 0x43, 0x5d, - 0x3a, 0xf9, 0x2e, 0xac, 0x81, 0xbd, 0xe7, 0xaa, 0x5e, 0xb3, 0x19, 0x7e, 0x4a, 0x84, 0x9f, 0xc9, - 0xb3, 0x80, 0x08, 0xc7, 0x6b, 0x71, 0x4d, 0x35, 0x33, 0xce, 0xf1, 0x97, 0xb9, 0xc0, 0xcc, 0xfb, - 0xca, 0xce, 0xbc, 0xaf, 0xba, 0xb0, 0xa6, 0x1a, 0xf6, 0xff, 0x0c, 0xfa, 0x73, 0x0e, 0xd6, 0x98, - 0x88, 0xdc, 0x17, 0xc2, 0xf1, 0xa3, 0x38, 0x1c, 0x25, 0xc3, 0xe6, 0xe3, 0xe0, 0x50, 0xa7, 0xda, - 0x66, 0x4a, 0x48, 0xda, 0x22, 0xb7, 0xa4, 0x2d, 0xee, 0xe2, 0x4b, 0x3f, 0x08, 0xfb, 0x38, 0x74, - 0x82, 0x50, 0x17, 0x7a, 0xda, 0x34, 0x6b, 0x42, 0xee, 0xc2, 0x4a, 0x37, 0x18, 0x85, 0xbd, 0xe4, - 0x4a, 0x5a, 0x4f, 0xad, 0x15, 0x33, 0xa5, 0x66, 0xc6, 0x2c, 0xd3, 0x47, 0x85, 0xe5, 0x7d, 0x44, - 0xee, 0x4f, 0xf5, 0x91, 0x7c, 0x84, 0x57, 0x5a, 0xaf, 0xa5, 0x0e, 0x13, 0x6a, 0x36, 0x69, 0x4d, - 0xbf, 0xb7, 0xe0, 0x4a, 0x96, 0xc2, 0xbf, 0x3a, 0x18, 0x49, 0x45, 0x72, 0x73, 0x2b, 0x62, 0xcf, - 0xab, 0x48, 0x3e, 0xad, 0x48, 0xfa, 0x64, 0x2b, 0x64, 0x9e, 0x6c, 0xf4, 0x18, 0x6e, 0xcc, 0x94, - 0x69, 0x37, 0x18, 0x0c, 0xb1, 0x1f, 0xfe, 0x43, 0xb9, 0xae, 0x41, 0xa1, 0x13, 0x86, 0xba, 0x50, - 0x65, 0xa6, 0x04, 0xfa, 0x25, 0x5c, 0xef, 0x8a, 0x38, 0x53, 0x24, 0xd3, 0x6d, 0x4d, 0xb0, 0x1f, - 0x7b, 0xfd, 0x05, 0xdb, 0x47, 0x15, 0x5a, 0xec, 0x8b, 0xd3, 0x05, 0x6b, 0xa2, 0x8a, 0xee, 0x40, - 0xe9, 0x20, 0x18, 0x06, 0x5e, 0x70, 0x34, 0xbe, 0xe0, 0x58, 0xd7, 0x61, 0x45, 0x4d, 0x2d, 0xf5, - 0x28, 0x28, 0x33, 0x23, 0xee, 0xd4, 0x7e, 0x3d, 0x6f, 0x58, 0xbf, 0x9d, 0x37, 0xac, 0xdf, 0xcf, - 0x1b, 0xd6, 0x4f, 0x7f, 0x34, 0x5e, 0x39, 0x2c, 0xca, 0xff, 0xcf, 0x7b, 0xff, 0x04, 0x00, 0x00, - 0xff, 0xff, 0x03, 0x63, 0x93, 0xf4, 0x90, 0x0e, 0x00, 0x00, + // 1250 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x5d, 0x6f, 0x1b, 0x45, + 0x17, 0x7e, 0xd7, 0xbb, 0x76, 0xec, 0xe3, 0x38, 0x71, 0xe6, 0x4d, 0x83, 0x13, 0x45, 0xae, 0x19, + 0x21, 0x1a, 0x2a, 0x11, 0x15, 0x57, 0x02, 0x1a, 0x54, 0xa9, 0x24, 0x76, 0xd5, 0x05, 0x12, 0xca, + 0x38, 0x2d, 0x12, 0x17, 0x48, 0x13, 0x7b, 0x48, 0x57, 0x59, 0xef, 0x9a, 0xdd, 0x71, 0x12, 0xf7, + 0x82, 0x4b, 0x84, 0x84, 0xb8, 0x47, 0xdc, 0xf2, 0x67, 0xb8, 0xe4, 0x27, 0xa0, 0xf0, 0x23, 0x90, + 0xb8, 0x01, 0xcd, 0xd7, 0xee, 0xfa, 0x33, 0xa4, 0x70, 0xb7, 0xe7, 0x39, 0x1f, 0xf3, 0xcc, 0x39, + 0x67, 0xce, 0xcc, 0x42, 0x65, 0x10, 0x79, 0xe7, 0x94, 0xb3, 0xdd, 0x41, 0x14, 0xf2, 0x10, 0x15, + 0xbd, 0x80, 0xb3, 0x28, 0xa0, 0x3e, 0xfe, 0x14, 0x4a, 0x6e, 0xd0, 0x63, 0x97, 0x87, 0x8c, 0x53, + 0xd4, 0x80, 0xf2, 0x41, 0xe8, 0x0f, 0xfb, 0xc1, 0x27, 0xf4, 0x84, 0xf9, 0x35, 0xab, 0x61, 0xed, + 0x94, 0x48, 0x16, 0x12, 0x16, 0xc7, 0x5e, 0x9f, 0x7d, 0x36, 0xa4, 0x01, 0x1f, 0xf6, 0x6b, 0x39, + 0x65, 0x91, 0x81, 0xf0, 0x9f, 0x16, 0x94, 0x1e, 0x47, 0xb4, 0xcf, 0x64, 0xc4, 0x2d, 0x28, 0x92, + 0xf0, 0x22, 0x1b, 0x2e, 0x91, 0xd1, 0x9b, 0xb0, 0xe2, 0x06, 0xe7, 0x2c, 0x8a, 0x59, 0x3b, 0xa0, + 0x27, 0x3e, 0xeb, 0xc9, 0x70, 0x45, 0x32, 0x81, 0xa2, 0x6d, 0x28, 0x1d, 0xd0, 0xee, 0x0b, 0x76, + 0x3c, 0x1a, 0xb0, 0x9a, 0x2d, 0x83, 0xa4, 0x40, 0xa2, 0xed, 0x78, 0x2f, 0x59, 0xcd, 0x69, 0x58, + 0x3b, 0x15, 0x92, 0x02, 0x93, 0x7c, 0xf3, 0x53, 0x7c, 0x11, 0x86, 0x65, 0x42, 0x83, 0xd3, 0x84, + 0x43, 0x41, 0x72, 0x18, 0xc3, 0xd0, 0x1d, 0x28, 0x3c, 0xf6, 0x98, 0xdf, 0x8b, 0x6b, 0x4b, 0x0d, + 0x7b, 0xa7, 0xdc, 0x5c, 0xdd, 0x35, 0xf9, 0xdb, 0x95, 0x38, 0xd1, 0x6a, 0x8c, 0x61, 0xc5, 0xed, + 0x0f, 0xc2, 0x88, 0x13, 0x16, 0x0f, 0xc2, 0x20, 0x66, 0xa8, 0x0a, 0x76, 0x3b, 0x8a, 0xf4, 0xde, + 0xc5, 0x27, 0xfe, 0x06, 0xaa, 0xfb, 0x7e, 0xd8, 0x3d, 0x6b, 0x51, 0x4e, 0x09, 0xfb, 0x7a, 0xc8, + 0x62, 0x8e, 0xd6, 0x21, 0x2f, 0xab, 0xa0, 0xed, 0x94, 0x20, 0x50, 0x99, 0x49, 0x9d, 0x66, 0x25, + 0x08, 0x54, 0xfa, 0xcb, 0x54, 0x38, 0x44, 0x09, 0x02, 0xed, 0xf8, 0x5e, 0x57, 0xa5, 0xc0, 0x21, + 0x4a, 0x40, 0x08, 0x9c, 0xe7, 0x1e, 0xbb, 0xd0, 0xfb, 0x96, 0xdf, 0xd8, 0x85, 0xb5, 0xcc, 0xfa, + 0x9a, 0xe6, 0x06, 0x14, 0x48, 0x78, 0xe1, 0xb6, 0xe2, 0x9a, 0xd5, 0xb0, 0x77, 0x1c, 0xa2, 0x25, + 0x99, 0x5d, 0x59, 0x7e, 0xa1, 0xca, 0x49, 0x55, 0x0a, 0xe0, 0x4d, 0xc8, 0xcb, 0x54, 0x8b, 0x5d, + 0xa6, 0xbe, 0xe2, 0x13, 0xff, 0x65, 0x41, 0xe9, 0x90, 0x5e, 0x4a, 0x1a, 0x31, 0x7a, 0x08, 0xc5, + 0x0e, 0xa7, 0x41, 0x8f, 0x46, 0x3d, 0x69, 0x54, 0x6e, 0xbe, 0x9e, 0xa6, 0x30, 0x31, 0xdb, 0x35, + 0x36, 0xed, 0x80, 0x47, 0x23, 0x92, 0xb8, 0xa0, 0x3d, 0x58, 0xd2, 0x3d, 0x21, 0x39, 0x94, 0x9b, + 0x8d, 0x59, 0xde, 0x49, 0xdb, 0x08, 0x67, 0xe3, 0xb0, 0xf5, 0x01, 0x54, 0xc6, 0xc2, 0x0a, 0xae, + 0x67, 0x6c, 0x64, 0x2a, 0x72, 0xc6, 0x46, 0x22, 0x77, 0xe7, 0xd4, 0x1f, 0xaa, 0x3c, 0x3b, 0x44, + 0x09, 0x7b, 0xb9, 0xf7, 0xad, 0xad, 0x3d, 0x58, 0xce, 0x46, 0xbd, 0x89, 0x2f, 0xfe, 0x12, 0xd0, + 0x41, 0xc4, 0x28, 0x67, 0x92, 0xde, 0x21, 0x8b, 0x63, 0x7a, 0xca, 0xe6, 0x57, 0x5a, 0x55, 0x2f, + 0x97, 0xad, 0xde, 0x36, 0x94, 0xdc, 0xd8, 0x6c, 0xdc, 0x96, 0x7d, 0x99, 0x02, 0xf8, 0x2e, 0xa0, + 0x16, 0xf3, 0x19, 0x67, 0xfa, 0xfc, 0x2e, 0x88, 0x8f, 0x3b, 0x86, 0xcb, 0xf5, 0xb6, 0xe8, 0x0e, + 0x38, 0xe2, 0xe8, 0x4a, 0x2a, 0xe5, 0xe6, 0xff, 0xd3, 0x4c, 0x27, 0x73, 0x82, 0x48, 0x03, 0xec, + 0x99, 0xa0, 0xfa, 0xb8, 0x5f, 0xb3, 0xc1, 0x19, 0xad, 0x6c, 0x96, 0xb2, 0x27, 0x97, 0x4a, 0x06, + 0x88, 0x5e, 0xea, 0x91, 0xd9, 0xeb, 0xab, 0x2e, 0x85, 0xbf, 0xd0, 0xa8, 0x38, 0x12, 0x47, 0x42, + 0xab, 0x7c, 0xe4, 0xf7, 0xfc, 0x2d, 0x4f, 0xf0, 0x10, 0xb1, 0xc5, 0x19, 0x8a, 0x6b, 0x76, 0xc3, + 0x16, 0xb1, 0xa5, 0x80, 0xef, 0x43, 0xa1, 0xd3, 0x7d, 0xc1, 0xfa, 0x14, 0xbd, 0x25, 0x1a, 0xb5, + 0xc7, 0x2e, 0x59, 0xac, 0xdb, 0x7c, 0x75, 0x22, 0x7d, 0xc4, 0xe8, 0xf1, 0xf7, 0x96, 0x66, 0x3f, + 0x87, 0x51, 0x41, 0xae, 0x1d, 0xd7, 0x9c, 0xa9, 0x89, 0x23, 0x70, 0xa2, 0xd5, 0xa8, 0x0d, 0x55, + 0x37, 0x18, 0x0c, 0x79, 0x8b, 0x7d, 0xe5, 0x05, 0x1e, 0xf7, 0xc2, 0x20, 0xae, 0x15, 0xa4, 0xcb, + 0x66, 0x76, 0xe9, 0x31, 0x0b, 0x32, 0xe5, 0x82, 0xbf, 0xb5, 0x60, 0x75, 0x02, 0xbc, 0x86, 0x57, + 0x6e, 0x31, 0xaf, 0x77, 0x93, 0x91, 0x69, 0x4b, 0xc3, 0xfa, 0x5c, 0x36, 0xe3, 0x13, 0xf4, 0x67, + 0x0b, 0xd6, 0x67, 0x19, 0xcc, 0x64, 0x53, 0x07, 0x78, 0x1a, 0x79, 0x7d, 0x1a, 0x8d, 0x3e, 0x66, + 0x23, 0x7d, 0x7b, 0x64, 0x10, 0xf4, 0x39, 0x6c, 0x4c, 0xc4, 0xfa, 0xb0, 0xab, 0x52, 0xa4, 0x48, + 0xdd, 0x9e, 0x4b, 0x4a, 0xd9, 0x91, 0x39, 0xee, 0xf8, 0x0f, 0x0b, 0x6e, 0xcd, 0x54, 0xa5, 0xdd, + 0x67, 0x65, 0x1b, 0xfd, 0x2e, 0x54, 0x9f, 0x8b, 0xc1, 0xd0, 0x62, 0x31, 0xf7, 0x02, 0x2a, 0x2c, + 0x75, 0x7b, 0x4e, 0xe1, 0xc8, 0x85, 0xa2, 0xc4, 0x0e, 0xe9, 0x40, 0xd3, 0x7c, 0xfb, 0x1a, 0x9a, + 0xbb, 0xc6, 0x5e, 0xcf, 0x4d, 0x23, 0x0a, 0x32, 0x72, 0x8e, 0x9b, 0x4b, 0x41, 0x0a, 0x62, 0x22, + 0x8e, 0x39, 0xdc, 0x68, 0xaa, 0x85, 0xb0, 0x6d, 0x26, 0xc9, 0x18, 0x93, 0xc5, 0x67, 0xf2, 0x01, + 0x40, 0x6a, 0xaa, 0x8f, 0xfb, 0x82, 0xfe, 0xcc, 0x18, 0xe3, 0x27, 0xb0, 0x6d, 0xc6, 0xdc, 0x0d, + 0x16, 0x34, 0xdd, 0x92, 0x4b, 0xbb, 0x05, 0xb7, 0xc1, 0x7e, 0x46, 0x5c, 0x71, 0xd5, 0xc9, 0xd3, + 0x6a, 0x4a, 0xa4, 0x25, 0xe1, 0xf2, 0x24, 0x8c, 0xb9, 0x71, 0x11, 0xdf, 0x02, 0x7b, 0x1a, 0x46, + 0x5c, 0x32, 0xae, 0x10, 0xf9, 0x8d, 0xdf, 0x03, 0xe7, 0x28, 0xec, 0x31, 0xb4, 0x02, 0x39, 0xb7, + 0xa5, 0x63, 0xe4, 0xdc, 0x16, 0xba, 0x2d, 0xc3, 0xeb, 0x19, 0x52, 0x49, 0x37, 0xf7, 0x8c, 0xb8, + 0x44, 0x68, 0xf0, 0x23, 0xa8, 0x0a, 0xc7, 0x0e, 0xa7, 0x3c, 0x19, 0x61, 0x1b, 0x50, 0x10, 0x58, + 0x12, 0x48, 0x4b, 0xf2, 0x42, 0x10, 0x76, 0x66, 0x88, 0x49, 0x01, 0xff, 0x60, 0x01, 0x98, 0x10, + 0xc3, 0x18, 0x61, 0xc5, 0x44, 0xba, 0x96, 0x9b, 0x2b, 0xe9, 0x92, 0x02, 0x25, 0x8a, 0xe5, 0x3b, + 0x99, 0x6b, 0x78, 0x7a, 0xbe, 0x25, 0x2a, 0x92, 0xb9, 0xac, 0x77, 0xcc, 0x38, 0xd3, 0x85, 0xaa, + 0xa6, 0xf6, 0x0a, 0xd7, 0x29, 0x13, 0x37, 0x40, 0xe5, 0xc0, 0x1f, 0xc6, 0x9c, 0x45, 0x9a, 0x91, + 0x78, 0x2e, 0x28, 0x20, 0xd9, 0x51, 0x0a, 0xcc, 0xde, 0x14, 0x7a, 0x03, 0xf2, 0x82, 0xa9, 0x39, + 0x93, 0x93, 0xdb, 0x50, 0x4a, 0xdc, 0x81, 0xfc, 0xfc, 0x39, 0x80, 0xc0, 0x91, 0x8f, 0x43, 0x5d, + 0x3a, 0xf9, 0x2e, 0xac, 0x82, 0x7d, 0xe8, 0xa9, 0x5e, 0xb3, 0x89, 0xf8, 0x94, 0x08, 0xbd, 0x94, + 0x67, 0x41, 0x20, 0x54, 0x5c, 0x8b, 0x6b, 0xaa, 0x99, 0xc5, 0x1c, 0x7f, 0x95, 0x0b, 0xcc, 0xbc, + 0xaf, 0xec, 0xcc, 0xfb, 0xaa, 0x03, 0x6b, 0xaa, 0x61, 0xff, 0xcb, 0xa0, 0x3f, 0xe5, 0x60, 0x8d, + 0xb0, 0xd8, 0x7b, 0xc9, 0xdc, 0x20, 0xe6, 0xd1, 0x30, 0x19, 0x36, 0x1f, 0x85, 0x27, 0x3a, 0xd5, + 0x36, 0x51, 0x42, 0xd2, 0x16, 0xb9, 0x05, 0x6d, 0x71, 0x4f, 0xbc, 0xf4, 0xc3, 0xa8, 0x27, 0x86, + 0x4e, 0x18, 0xe9, 0x42, 0x4f, 0x9a, 0x66, 0x4d, 0xd0, 0x3d, 0x58, 0xea, 0x84, 0xc3, 0xa8, 0x9b, + 0x5c, 0x49, 0x1b, 0xa9, 0xb5, 0x62, 0xa6, 0xd4, 0xc4, 0x98, 0x65, 0xfa, 0x28, 0xbf, 0xb8, 0x8f, + 0xd0, 0xc3, 0x89, 0x3e, 0x92, 0x8f, 0xf0, 0x72, 0xf3, 0xb5, 0xd4, 0x61, 0x4c, 0x4d, 0xc6, 0xad, + 0xf1, 0x77, 0x16, 0x2c, 0x67, 0x29, 0xfc, 0xa3, 0x83, 0x91, 0x54, 0x24, 0x37, 0xb3, 0x22, 0xf6, + 0xac, 0x8a, 0x38, 0x69, 0x45, 0xd2, 0x27, 0x5b, 0x3e, 0xf3, 0x64, 0xc3, 0x67, 0xb0, 0x39, 0x55, + 0xa6, 0x83, 0xb0, 0x3f, 0x10, 0xfd, 0xf0, 0x2f, 0xca, 0xb5, 0x0e, 0xf9, 0x76, 0x14, 0xe9, 0x42, + 0x95, 0x88, 0x12, 0xf0, 0x03, 0xb8, 0xd5, 0x61, 0x3c, 0x53, 0x24, 0xd3, 0x6d, 0x0d, 0xb0, 0x8f, + 0xd8, 0xc5, 0x9c, 0xed, 0x0b, 0x15, 0xde, 0x87, 0xe2, 0x71, 0x38, 0x08, 0xfd, 0xf0, 0x74, 0x74, + 0xcd, 0xa1, 0xad, 0xc1, 0x92, 0x9a, 0x49, 0xea, 0xca, 0x2f, 0x11, 0x23, 0xee, 0x57, 0x7f, 0xb9, + 0xaa, 0x5b, 0xbf, 0x5e, 0xd5, 0xad, 0xdf, 0xae, 0xea, 0xd6, 0x8f, 0xbf, 0xd7, 0xff, 0x77, 0x52, + 0x90, 0x7f, 0x97, 0xf7, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x5d, 0xc5, 0x2e, 0x66, 0x6e, 0x0e, + 0x00, 0x00, } diff --git a/internal/private.proto b/internal/private.proto index 1686b3be2..4e3261079 100644 --- a/internal/private.proto +++ b/internal/private.proto @@ -186,8 +186,7 @@ message ResizeInstructionComplete { } message SetCoordinatorMessage { - Node Old = 1; - Node New = 2; + Node New = 1; } message Topology { diff --git a/server.go b/server.go index 7652a6c5b..63c14a88e 100644 --- a/server.go +++ b/server.go @@ -442,7 +442,7 @@ func (s *Server) ReceiveMessage(pb proto.Message) error { return err } case *internal.SetCoordinatorMessage: - s.Cluster.SetCoordinator(DecodeNode(obj.Old), DecodeNode(obj.New)) + s.Cluster.SetCoordinator(DecodeNode(obj.New)) case *internal.NodeStateMessage: err := s.Cluster.ReceiveNodeState(obj.NodeID, obj.State) if err != nil { From 346e92a91dd2e9d7449953e4d6edf1e9004c0833 Mon Sep 17 00:00:00 2001 From: Travis Turner Date: Fri, 2 Feb 2018 15:58:08 -0600 Subject: [PATCH 3/3] return 0 values for errors. panic on unmarshal node meta data --- cluster.go | 6 +++--- gossip/gossip.go | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cluster.go b/cluster.go index d531c90d6..76642107b 100644 --- a/cluster.go +++ b/cluster.go @@ -633,12 +633,12 @@ func (c *Cluster) diff(other *Cluster) (action string, nodeID string, err error) lenTo := len(other.Nodes) // Determine if a node is being added or removed. if lenFrom == lenTo { - return action, nodeID, errors.New("clusters are the same size") + return "", "", errors.New("clusters are the same size") } if lenFrom < lenTo { // Adding a node. if lenTo-lenFrom > 1 { - return action, nodeID, errors.New("adding more than one node at a time is not supported") + return "", "", errors.New("adding more than one node at a time is not supported") } action = ResizeJobActionAdd // Determine the node ID that is being added. @@ -651,7 +651,7 @@ func (c *Cluster) diff(other *Cluster) (action string, nodeID string, err error) } else if lenFrom > lenTo { // Removing a node. if lenFrom-lenTo > 1 { - return action, nodeID, errors.New("removing more than one node at a time is not supported") + return "", "", errors.New("removing more than one node at a time is not supported") } action = ResizeJobActionRemove // Determine the node ID that is being removed. diff --git a/gossip/gossip.go b/gossip/gossip.go index d0868be92..acfad66a1 100644 --- a/gossip/gossip.go +++ b/gossip/gossip.go @@ -384,8 +384,7 @@ func (g *GossipEventReceiver) listen() { // Get the node from the event.Node meta data. var n internal.Node if err := proto.Unmarshal(e.Node.Meta, &n); err != nil { - // TODO: consider logging error - continue + panic("failed to unmarshal event node meta data") } node := pilosa.DecodeNode(&n)