WIP: Wait for nodeState on Holder.Open().

Implement prefect in Cluster so a node can start http listener in a
restricted mode.
Adjust tests; particularly start test.Holder in state Normal.

TODO:
- [ ] fix test TestMain_SendReceiveMessage
- [ ] add additional tests for `nodeState`
This commit is contained in:
Travis Turner 2017-11-21 16:23:20 -06:00
parent a98b862fca
commit a13db570cc
No known key found for this signature in database
GPG key ID: 7F08008DFD9314C9
9 changed files with 427 additions and 160 deletions

View file

@ -126,6 +126,7 @@ const (
MessageTypeResizeInstruction = 10
MessageTypeResizeInstructionComplete = 11
MessageTypeSetCoordinator = 12
MessageTypeNodeState = 13
)
// MarshalMessage encodes the protobuf message into a byte slice.
@ -156,6 +157,8 @@ func MarshalMessage(m proto.Message) ([]byte, error) {
typ = MessageTypeResizeInstructionComplete
case *internal.SetCoordinatorMessage:
typ = MessageTypeSetCoordinator
case *internal.NodeStateMessage:
typ = MessageTypeNodeState
default:
return nil, fmt.Errorf("message type not implemented for marshalling: %s", reflect.TypeOf(obj))
}
@ -196,6 +199,8 @@ func UnmarshalMessage(buf []byte) (proto.Message, error) {
m = &internal.ResizeInstructionComplete{}
case MessageTypeSetCoordinator:
m = &internal.SetCoordinatorMessage{}
case MessageTypeNodeState:
m = &internal.NodeStateMessage{}
default:
return nil, fmt.Errorf("invalid message type: %d", typ)
}

View file

@ -46,6 +46,10 @@ const (
ClusterStateNormal = "NORMAL"
ClusterStateResizing = "RESIZING"
// NodeState represents the state of a node during startup.
NodeStateLoading = "LOADING"
NodeStateReady = "READY"
// ResizeJob states.
ResizeJobStateRunning = "RUNNING"
// Final states.
@ -285,6 +289,41 @@ func (c *Cluster) setState(state string) {
c.State = state
}
func (c *Cluster) setNodeState(state string) {
if c.IsCoordinator() {
c.Topology.nodeStates[c.URI] = state
return
}
// Send node state to coordinator.
ns := &internal.NodeStateMessage{
URI: c.URI.Encode(),
State: state,
}
node := &Node{
URI: c.Coordinator,
}
if err := c.Broadcaster.SendTo(node, ns); err != nil {
c.logger().Printf("sending node state error: err=%s", err)
}
}
func (c *Cluster) ReceiveNodeState(uri URI, state string) error {
if !c.IsCoordinator() {
return nil
}
c.Topology.nodeStates[uri] = state
// Set cluster state to NORMAL.
if c.haveTopologyAgreement() && c.allNodesReady() {
return c.setStateAndBroadcast(ClusterStateNormal)
}
return nil
}
// localNode is not being used.
//func (c *Cluster) localNode() *Node {
// return c.NodeByURI(c.URI)
@ -693,6 +732,15 @@ func (c *Cluster) haveTopologyAgreement() bool {
return URISlicesAreEqual(c.Topology.NodeSet, c.NodeSet())
}
func (c *Cluster) allNodesReady() bool {
for _, uri := range c.Topology.NodeSet {
if c.Topology.nodeStates[uri] != NodeStateReady {
return false
}
}
return true
}
func (c *Cluster) handleNodeAction(nodeAction nodeAction) error {
j, err := c.generateResizeJob(nodeAction)
if err != nil {
@ -1130,10 +1178,16 @@ func (u NodeSet) ToStrings() []string {
type Topology struct {
mu sync.RWMutex
NodeSet []URI
// nodeStates holds the state of each node according to
// the coordinator. Used during startup and data load.
nodeStates map[URI]string
}
func NewTopology() *Topology {
return &Topology{}
return &Topology{
nodeStates: make(map[URI]string),
}
}
// ContainsURI returns true if uri matches one of the topology's uris.
@ -1241,9 +1295,9 @@ func decodeTopology(topology *internal.Topology) (*Topology, error) {
return nil, nil
}
t := &Topology{
NodeSet: decodeURIs(topology.NodeSet),
}
t := NewTopology()
t.NodeSet = decodeURIs(topology.NodeSet)
return t, nil
}
@ -1302,9 +1356,19 @@ func (c *Cluster) nodeJoin(uri URI) error {
return err
}
// If the result of the previous AddNode completed the joining of nodes
// in the topology, then change the state to NORMAL.
if c.haveTopologyAgreement() {
// Only change to normal if there is no existing data. Otherwise,
// the coordinator needs to wait to receive READY messages (nodeStates)
// from remote nodes before setting the cluster to state NORMAL.
if !c.Holder.HasData() {
// If the result of the previous AddNode completed the joining of nodes
// in the topology, then change the state to NORMAL.
if c.haveTopologyAgreement() {
return c.setStateAndBroadcast(ClusterStateNormal)
}
return nil
}
if c.haveTopologyAgreement() && c.allNodesReady() {
return c.setStateAndBroadcast(ClusterStateNormal)
}

View file

@ -253,8 +253,8 @@ func TestCluster_ResizeStates(t *testing.T) {
}
// Verify topology file.
if !reflect.DeepEqual(node.Topology, expectedTop) {
t.Errorf("expected topology: %v, but got: %v", expectedTop, node.Topology)
if !reflect.DeepEqual(node.Topology.NodeSet, expectedTop.NodeSet) {
t.Errorf("expected topology: %v, but got: %v", expectedTop.NodeSet, node.Topology.NodeSet)
}
// Close TestCluster.
@ -344,10 +344,10 @@ func TestCluster_ResizeStates(t *testing.T) {
}
// Verify topology file.
if !reflect.DeepEqual(node0.Topology, expectedTop) {
t.Errorf("expected node0 topology: %v, but got: %v", expectedTop, node0.Topology)
} else if !reflect.DeepEqual(node1.Topology, expectedTop) {
t.Errorf("expected node1 topology: %v, but got: %v", expectedTop, node1.Topology)
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)
}
// Close TestCluster.
@ -436,10 +436,10 @@ func TestCluster_ResizeStates(t *testing.T) {
}
// Verify topology file.
if !reflect.DeepEqual(node0.Topology, expectedTop) {
t.Errorf("expected node0 topology: %v, but got: %v", expectedTop, node0.Topology)
} else if !reflect.DeepEqual(node1.Topology, expectedTop) {
t.Errorf("expected node1 topology: %v, but got: %v", expectedTop, node1.Topology)
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)
}
// Verify that node-1 contains the fragment (i/f/standard/1) transferred from node-0.

View file

@ -109,7 +109,7 @@ func BuildRouters(handler *Handler) {
loadRestricted(router, handler)
handler.RestrictedRouter = router
handler.SetNormal()
handler.SetRestricted()
}
// SetNormal is a method of the SecurityManager interface which provides normal URI routing.
@ -184,7 +184,7 @@ func loadNormal(router *mux.Router, handler *Handler) {
}
func (h *Handler) reportRestricted(w http.ResponseWriter, r *http.Request) {
http.Error(w, "not allowed during resize", http.StatusMethodNotAllowed)
http.Error(w, fmt.Sprintf("not allowed in cluster state %s", h.Cluster.State), http.StatusMethodNotAllowed)
}
func (h *Handler) methodNotAllowedHandler(w http.ResponseWriter, r *http.Request) {

View file

@ -29,6 +29,7 @@
CreateInputDefinitionMessage
DeleteInputDefinitionMessage
URI
NodeStateMessage
NodeStatus
ClusterStatus
Field
@ -670,6 +671,30 @@ func (m *URI) GetPort() uint32 {
return 0
}
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"`
}
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 (m *NodeStateMessage) GetURI() *URI {
if m != nil {
return m.URI
}
return nil
}
func (m *NodeStateMessage) GetState() string {
if m != nil {
return m.State
}
return ""
}
type NodeStatus struct {
URI *URI `protobuf:"bytes,1,opt,name=URI" json:"URI,omitempty"`
MaxSlices *MaxSlices `protobuf:"bytes,2,opt,name=MaxSlices" json:"MaxSlices,omitempty"`
@ -679,7 +704,7 @@ 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{21} }
func (*NodeStatus) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{22} }
func (m *NodeStatus) GetURI() *URI {
if m != nil {
@ -710,7 +735,7 @@ type ClusterStatus struct {
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{22} }
func (*ClusterStatus) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{23} }
func (m *ClusterStatus) GetState() string {
if m != nil {
@ -736,7 +761,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{23} }
func (*Field) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{24} }
func (m *Field) GetName() string {
if m != nil {
@ -775,7 +800,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{24} }
func (*DeleteViewMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{25} }
func (m *DeleteViewMessage) GetIndex() string {
if m != nil {
@ -809,7 +834,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{25} }
func (*ResizeInstruction) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{26} }
func (m *ResizeInstruction) GetJobID() int64 {
if m != nil {
@ -857,7 +882,7 @@ 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{26} }
func (*ResizeSource) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{27} }
func (m *ResizeSource) GetURI() *URI {
if m != nil {
@ -904,7 +929,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{27}
return fileDescriptorPrivate, []int{28}
}
func (m *ResizeInstructionComplete) GetJobID() int64 {
@ -936,7 +961,7 @@ type SetCoordinatorMessage struct {
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{28} }
func (*SetCoordinatorMessage) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{29} }
func (m *SetCoordinatorMessage) GetOld() *URI {
if m != nil {
@ -959,7 +984,7 @@ type Topology struct {
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{29} }
func (*Topology) Descriptor() ([]byte, []int) { return fileDescriptorPrivate, []int{30} }
func (m *Topology) GetNodeSet() []*URI {
if m != nil {
@ -990,6 +1015,7 @@ func init() {
proto.RegisterType((*CreateInputDefinitionMessage)(nil), "internal.CreateInputDefinitionMessage")
proto.RegisterType((*DeleteInputDefinitionMessage)(nil), "internal.DeleteInputDefinitionMessage")
proto.RegisterType((*URI)(nil), "internal.URI")
proto.RegisterType((*NodeStateMessage)(nil), "internal.NodeStateMessage")
proto.RegisterType((*NodeStatus)(nil), "internal.NodeStatus")
proto.RegisterType((*ClusterStatus)(nil), "internal.ClusterStatus")
proto.RegisterType((*Field)(nil), "internal.Field")
@ -1848,6 +1874,40 @@ func (m *URI) MarshalTo(dAtA []byte) (int, error) {
return i, nil
}
func (m *NodeStateMessage) 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 *NodeStateMessage) MarshalTo(dAtA []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.URI != nil {
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
}
if len(m.State) > 0 {
dAtA[i] = 0x12
i++
i = encodeVarintPrivate(dAtA, i, uint64(len(m.State)))
i += copy(dAtA[i:], m.State)
}
return i, nil
}
func (m *NodeStatus) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -1867,32 +1927,32 @@ func (m *NodeStatus) MarshalTo(dAtA []byte) (int, error) {
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
}
if m.MaxSlices != nil {
dAtA[i] = 0x12
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.MaxSlices.Size()))
n12, err := m.MaxSlices.MarshalTo(dAtA[i:])
n12, err := m.URI.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n12
}
if m.Schema != nil {
dAtA[i] = 0x1a
if m.MaxSlices != nil {
dAtA[i] = 0x12
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.Schema.Size()))
n13, err := m.Schema.MarshalTo(dAtA[i:])
i = encodeVarintPrivate(dAtA, i, uint64(m.MaxSlices.Size()))
n13, err := m.MaxSlices.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n13
}
if m.Schema != nil {
dAtA[i] = 0x1a
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.Schema.Size()))
n14, err := m.Schema.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n14
}
return i, nil
}
@ -2032,21 +2092,21 @@ func (m *ResizeInstruction) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.URI.Size()))
n14, err := m.URI.MarshalTo(dAtA[i:])
n15, err := m.URI.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n14
i += n15
}
if m.Coordinator != nil {
dAtA[i] = 0x1a
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.Coordinator.Size()))
n15, err := m.Coordinator.MarshalTo(dAtA[i:])
n16, err := m.Coordinator.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n15
i += n16
}
if len(m.Sources) > 0 {
for _, msg := range m.Sources {
@ -2064,11 +2124,11 @@ func (m *ResizeInstruction) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x2a
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.Schema.Size()))
n16, err := m.Schema.MarshalTo(dAtA[i:])
n17, err := m.Schema.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n16
i += n17
}
return i, nil
}
@ -2092,11 +2152,11 @@ func (m *ResizeSource) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.URI.Size()))
n17, err := m.URI.MarshalTo(dAtA[i:])
n18, err := m.URI.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n17
i += n18
}
if len(m.Index) > 0 {
dAtA[i] = 0x12
@ -2148,11 +2208,11 @@ func (m *ResizeInstructionComplete) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0x12
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.URI.Size()))
n18, err := m.URI.MarshalTo(dAtA[i:])
n19, err := m.URI.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n18
i += n19
}
if len(m.Error) > 0 {
dAtA[i] = 0x1a
@ -2182,21 +2242,21 @@ func (m *SetCoordinatorMessage) MarshalTo(dAtA []byte) (int, error) {
dAtA[i] = 0xa
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.Old.Size()))
n19, err := m.Old.MarshalTo(dAtA[i:])
n20, err := m.Old.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n19
i += n20
}
if m.New != nil {
dAtA[i] = 0x12
i++
i = encodeVarintPrivate(dAtA, i, uint64(m.New.Size()))
n20, err := m.New.MarshalTo(dAtA[i:])
n21, err := m.New.MarshalTo(dAtA[i:])
if err != nil {
return 0, err
}
i += n20
i += n21
}
return i, nil
}
@ -2613,6 +2673,20 @@ func (m *URI) Size() (n int) {
return n
}
func (m *NodeStateMessage) Size() (n int) {
var l int
_ = l
if m.URI != nil {
l = m.URI.Size()
n += 1 + l + sovPrivate(uint64(l))
}
l = len(m.State)
if l > 0 {
n += 1 + l + sovPrivate(uint64(l))
}
return n
}
func (m *NodeStatus) Size() (n int) {
var l int
_ = l
@ -5705,6 +5779,118 @@ func (m *URI) Unmarshal(dAtA []byte) error {
}
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 URI", 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.URI == nil {
m.URI = &URI{}
}
if err := m.URI.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field State", 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.State = string(dAtA[iNdEx:postIndex])
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 *NodeStatus) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@ -7071,79 +7257,80 @@ var (
func init() { proto.RegisterFile("private.proto", fileDescriptorPrivate) }
var fileDescriptorPrivate = []byte{
// 1179 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0x4f, 0x6f, 0xe3, 0x44,
0x14, 0xc7, 0x71, 0x92, 0x26, 0x2f, 0x9b, 0xdd, 0xec, 0xd0, 0xad, 0xd2, 0xaa, 0x4a, 0xc3, 0x1c,
0x68, 0x59, 0x89, 0x02, 0xad, 0x84, 0xa0, 0x08, 0x09, 0xb6, 0xc9, 0x6a, 0x0d, 0xb4, 0x5d, 0x26,
0xdd, 0x45, 0x70, 0x40, 0x9a, 0x26, 0x43, 0x6b, 0xd5, 0xb1, 0x83, 0x3d, 0x69, 0x9b, 0x3d, 0x70,
0x83, 0x03, 0x7c, 0x01, 0xee, 0x7c, 0x19, 0x8e, 0xdc, 0xb8, 0xa2, 0xf2, 0x21, 0x90, 0xb8, 0x80,
0xe6, 0x79, 0xc6, 0x76, 0xfe, 0x35, 0x6a, 0x6f, 0x7e, 0x6f, 0xde, 0x7b, 0xf3, 0x9b, 0xdf, 0xfb,
0x33, 0x63, 0xa8, 0x0e, 0x42, 0xf7, 0x82, 0x4b, 0xb1, 0x3d, 0x08, 0x03, 0x19, 0x90, 0x92, 0xeb,
0x4b, 0x11, 0xfa, 0xdc, 0xa3, 0x47, 0x50, 0x76, 0xfc, 0x9e, 0xb8, 0x3a, 0x10, 0x92, 0x93, 0x26,
0x54, 0xf6, 0x03, 0x6f, 0xd8, 0xf7, 0xbf, 0xe0, 0x27, 0xc2, 0xab, 0x5b, 0x4d, 0x6b, 0xab, 0xcc,
0xb2, 0x2a, 0x65, 0x71, 0xec, 0xf6, 0xc5, 0x97, 0x43, 0xee, 0xcb, 0x61, 0xbf, 0x9e, 0x8b, 0x2d,
0x32, 0x2a, 0xfa, 0xaf, 0x05, 0xe5, 0xa7, 0x21, 0xef, 0x0b, 0x8c, 0xb8, 0x06, 0x25, 0x16, 0x5c,
0x66, 0xc3, 0x25, 0x32, 0x79, 0x13, 0xee, 0x3b, 0xfe, 0x85, 0x08, 0x23, 0xd1, 0xf6, 0xf9, 0x89,
0x27, 0x7a, 0x18, 0xae, 0xc4, 0x26, 0xb4, 0x64, 0x1d, 0xca, 0xfb, 0xbc, 0x7b, 0x26, 0x8e, 0x47,
0x03, 0x51, 0xb7, 0x31, 0x48, 0xaa, 0x48, 0x56, 0x3b, 0xee, 0x2b, 0x51, 0xcf, 0x37, 0xad, 0xad,
0x2a, 0x4b, 0x15, 0x93, 0x78, 0x0b, 0x53, 0x78, 0x09, 0x85, 0x7b, 0x8c, 0xfb, 0xa7, 0x09, 0x86,
0x22, 0x62, 0x18, 0xd3, 0x91, 0x4d, 0x28, 0x3e, 0x75, 0x85, 0xd7, 0x8b, 0xea, 0x4b, 0x4d, 0x7b,
0xab, 0xb2, 0xf3, 0x60, 0xdb, 0xf0, 0xb7, 0x8d, 0x7a, 0xa6, 0x97, 0x29, 0x85, 0xfb, 0x4e, 0x7f,
0x10, 0x84, 0x92, 0x89, 0x68, 0x10, 0xf8, 0x91, 0x20, 0x35, 0xb0, 0xdb, 0x61, 0xa8, 0xcf, 0xae,
0x3e, 0xe9, 0x0f, 0x50, 0x7b, 0xe2, 0x05, 0xdd, 0xf3, 0x16, 0x97, 0x9c, 0x89, 0xef, 0x87, 0x22,
0x92, 0x64, 0x19, 0x0a, 0x98, 0x05, 0x6d, 0x17, 0x0b, 0x4a, 0x8b, 0x4c, 0x6a, 0x9a, 0x63, 0x41,
0x69, 0xd1, 0x1f, 0xa9, 0xc8, 0xb3, 0x58, 0x50, 0xda, 0x8e, 0xe7, 0x76, 0x63, 0x0a, 0xf2, 0x2c,
0x16, 0x08, 0x81, 0xfc, 0x4b, 0x57, 0x5c, 0xea, 0x73, 0xe3, 0x37, 0x75, 0xe0, 0x61, 0x66, 0x7f,
0x0d, 0x73, 0x05, 0x8a, 0x2c, 0xb8, 0x74, 0x5a, 0x51, 0xdd, 0x6a, 0xda, 0x5b, 0x79, 0xa6, 0x25,
0x64, 0x17, 0xd3, 0xaf, 0x96, 0x72, 0xb8, 0x94, 0x2a, 0xe8, 0x2a, 0x14, 0x90, 0x6a, 0x75, 0xca,
0xd4, 0x57, 0x7d, 0xd2, 0xff, 0x2c, 0x28, 0x1f, 0xf0, 0x2b, 0x84, 0x11, 0x91, 0x8f, 0xa1, 0xd4,
0x91, 0xdc, 0xef, 0xf1, 0xb0, 0x87, 0x46, 0x95, 0x9d, 0x37, 0x52, 0x0a, 0x13, 0xb3, 0x6d, 0x63,
0xd3, 0xf6, 0x65, 0x38, 0x62, 0x89, 0x0b, 0xd9, 0x83, 0x25, 0x5d, 0x13, 0x88, 0xa1, 0xb2, 0xd3,
0x9c, 0xe5, 0x9d, 0x94, 0x8d, 0x72, 0x36, 0x0e, 0x6b, 0x1f, 0x41, 0x75, 0x2c, 0xac, 0xc2, 0x7a,
0x2e, 0x46, 0x26, 0x23, 0xe7, 0x62, 0xa4, 0xb8, 0xbb, 0xe0, 0xde, 0x30, 0xe6, 0x39, 0xcf, 0x62,
0x61, 0x2f, 0xf7, 0x81, 0xb5, 0xb6, 0x07, 0xf7, 0xb2, 0x51, 0x6f, 0xe3, 0x4b, 0xbf, 0x05, 0xb2,
0x1f, 0x0a, 0x2e, 0x05, 0xc2, 0x3b, 0x10, 0x51, 0xc4, 0x4f, 0xc5, 0xfc, 0x4c, 0xc7, 0xd9, 0xcb,
0x65, 0xb3, 0xb7, 0x0e, 0x65, 0x27, 0x32, 0x07, 0xb7, 0xb1, 0x2e, 0x53, 0x05, 0x7d, 0x0c, 0xa4,
0x25, 0x3c, 0x21, 0x85, 0xee, 0xdf, 0x1b, 0xe2, 0xd3, 0x8e, 0xc1, 0xb2, 0xd8, 0x96, 0x6c, 0x42,
0x5e, 0xb5, 0x2e, 0x42, 0xa9, 0xec, 0xbc, 0x9e, 0x32, 0x9d, 0xcc, 0x09, 0x86, 0x06, 0xd4, 0x35,
0x41, 0x75, 0xbb, 0x2f, 0x38, 0xe0, 0x8c, 0x52, 0x36, 0x5b, 0xd9, 0x93, 0x5b, 0x25, 0x03, 0x44,
0x6f, 0xf5, 0x89, 0x39, 0xeb, 0x5d, 0xb7, 0xa2, 0xdf, 0x68, 0xad, 0x6a, 0x89, 0x43, 0xb5, 0x1a,
0xfb, 0xe0, 0xf7, 0xfc, 0x23, 0x4f, 0xe0, 0x50, 0xb1, 0x55, 0x0f, 0x45, 0x75, 0xbb, 0x69, 0xab,
0xd8, 0x28, 0xd0, 0x5d, 0x28, 0x76, 0xba, 0x67, 0xa2, 0xcf, 0xc9, 0x5b, 0xaa, 0x50, 0x7b, 0xe2,
0x4a, 0x44, 0xba, 0xcc, 0x1f, 0x4c, 0xd0, 0xc7, 0xcc, 0x3a, 0xfd, 0xc5, 0xd2, 0xe8, 0xe7, 0x20,
0x2a, 0xe2, 0xde, 0x51, 0x3d, 0x3f, 0x35, 0x71, 0x94, 0x9e, 0xe9, 0x65, 0xd2, 0x86, 0x9a, 0xe3,
0x0f, 0x86, 0xb2, 0x25, 0xbe, 0x73, 0x7d, 0x57, 0xba, 0x81, 0x1f, 0xd5, 0x8b, 0xe8, 0xb2, 0x9a,
0xdd, 0x7a, 0xcc, 0x82, 0x4d, 0xb9, 0xd0, 0x9f, 0x2c, 0x78, 0x30, 0xa1, 0x5c, 0x80, 0x2b, 0x77,
0x33, 0xae, 0xf7, 0x93, 0x91, 0x69, 0xa3, 0x61, 0x63, 0x2e, 0x9a, 0xf1, 0x09, 0xfa, 0x9b, 0x05,
0xcb, 0xb3, 0x0c, 0x66, 0xa2, 0x69, 0x00, 0x3c, 0x0f, 0xdd, 0x3e, 0x0f, 0x47, 0x9f, 0x8b, 0x91,
0xbe, 0x3d, 0x32, 0x1a, 0xf2, 0x15, 0xac, 0x4c, 0xc4, 0xfa, 0xb4, 0x1b, 0x53, 0x14, 0x83, 0xda,
0x98, 0x0b, 0x2a, 0xb6, 0x63, 0x73, 0xdc, 0xe9, 0x3f, 0x16, 0x3c, 0x9a, 0xb9, 0x94, 0x56, 0x9f,
0x95, 0x2d, 0xf4, 0xc7, 0x50, 0x7b, 0xa9, 0x06, 0x43, 0x4b, 0x44, 0xd2, 0xf5, 0xb9, 0xb2, 0xd4,
0xe5, 0x39, 0xa5, 0x27, 0x0e, 0x94, 0x50, 0x77, 0xc0, 0x07, 0x1a, 0xe6, 0xdb, 0x0b, 0x60, 0x6e,
0x1b, 0x7b, 0x3d, 0x37, 0x8d, 0xa8, 0xc0, 0xe0, 0x1c, 0x37, 0x97, 0x02, 0x0a, 0x6a, 0x22, 0x8e,
0x39, 0xdc, 0x6a, 0xaa, 0x05, 0xb0, 0x6e, 0x26, 0xc9, 0x18, 0x92, 0x9b, 0x7b, 0xf2, 0x43, 0x80,
0xd4, 0x54, 0xb7, 0xfb, 0x0d, 0xf5, 0x99, 0x31, 0xa6, 0xcf, 0x60, 0xdd, 0x8c, 0xb9, 0x5b, 0x6c,
0x68, 0xaa, 0x25, 0x97, 0x56, 0x0b, 0x6d, 0x83, 0xfd, 0x82, 0x39, 0xea, 0xaa, 0xc3, 0x6e, 0x35,
0x29, 0xd2, 0x92, 0x72, 0x79, 0x16, 0x44, 0xd2, 0xb8, 0xa8, 0x6f, 0xa5, 0x7b, 0x1e, 0x84, 0x12,
0x11, 0x57, 0x19, 0x7e, 0xd3, 0x9f, 0x2d, 0x80, 0xc3, 0xa0, 0x27, 0x3a, 0x92, 0xcb, 0x61, 0x44,
0x36, 0x30, 0x2a, 0xc6, 0xaa, 0xec, 0x54, 0xd3, 0x33, 0xbd, 0x60, 0x0e, 0xc3, 0xfd, 0xde, 0xcb,
0x5c, 0x84, 0xd3, 0x13, 0x26, 0x59, 0x62, 0x99, 0xeb, 0x72, 0xcb, 0x0c, 0x14, 0x4d, 0x55, 0x2d,
0xb5, 0x8f, 0xf5, 0x1a, 0x34, 0xa7, 0x87, 0x50, 0xdd, 0xf7, 0x86, 0x91, 0x14, 0xa1, 0x86, 0xa3,
0x6e, 0x12, 0xc9, 0x65, 0x52, 0x7f, 0x28, 0x90, 0x4d, 0x58, 0x42, 0xc8, 0x42, 0xea, 0xbe, 0x9d,
0x00, 0x6a, 0x56, 0x69, 0x07, 0x0a, 0xf3, 0xdb, 0x8d, 0x40, 0x1e, 0xdf, 0x60, 0x9a, 0x21, 0x7c,
0x7e, 0xd5, 0xc0, 0x3e, 0x70, 0xe3, 0x94, 0xda, 0x4c, 0x7d, 0xa2, 0x86, 0x5f, 0x61, 0xc9, 0x29,
0x0d, 0x57, 0xb7, 0xcf, 0xc3, 0x38, 0x85, 0x6a, 0x5c, 0xde, 0xe5, 0x9e, 0x30, 0xcf, 0x18, 0x3b,
0xf3, 0x8c, 0xf9, 0xd3, 0x82, 0x87, 0x4c, 0x44, 0xee, 0x2b, 0xe1, 0xf8, 0x91, 0x0c, 0x87, 0x49,
0xfb, 0x7d, 0x16, 0x9c, 0x38, 0x2d, 0x8c, 0x6a, 0xb3, 0x58, 0x30, 0x39, 0xca, 0xcd, 0xcd, 0xd1,
0x3b, 0xea, 0xe1, 0x1b, 0x84, 0x3d, 0xd5, 0x83, 0x41, 0xa8, 0x59, 0x9f, 0x30, 0xcc, 0x5a, 0x90,
0x77, 0x61, 0xa9, 0x13, 0x0c, 0xc3, 0x6e, 0x32, 0xa0, 0x57, 0x52, 0xe3, 0x18, 0x55, 0xbc, 0xcc,
0x8c, 0x59, 0x26, 0xa7, 0x85, 0x05, 0x39, 0xfd, 0xd1, 0x82, 0x7b, 0xd9, 0x18, 0x8b, 0x4b, 0x2c,
0xe1, 0x32, 0x37, 0x93, 0x4b, 0x7b, 0x16, 0x97, 0xf9, 0x94, 0xcb, 0xf4, 0xf9, 0x51, 0xc8, 0x3c,
0x3f, 0xe8, 0x19, 0xac, 0x4e, 0x11, 0xbc, 0x1f, 0xf4, 0x07, 0x2a, 0x93, 0x77, 0x25, 0x7a, 0x19,
0x0a, 0xed, 0x30, 0xd4, 0x14, 0x97, 0x59, 0x2c, 0xd0, 0xaf, 0xe1, 0x51, 0x47, 0xc8, 0x0c, 0xbf,
0xa6, 0x48, 0x36, 0xc0, 0x3e, 0xf2, 0x7a, 0x73, 0x4e, 0x7e, 0xe4, 0xf5, 0x94, 0xc1, 0xa1, 0xb8,
0x9c, 0xb3, 0xe1, 0xa1, 0xb8, 0xa4, 0xbb, 0x50, 0x3a, 0x0e, 0x06, 0x81, 0x17, 0x9c, 0x8e, 0xb2,
0x5d, 0x60, 0xdd, 0xd4, 0x05, 0x4f, 0x6a, 0xbf, 0x5f, 0x37, 0xac, 0x3f, 0xae, 0x1b, 0xd6, 0x5f,
0xd7, 0x0d, 0xeb, 0xd7, 0xbf, 0x1b, 0xaf, 0x9d, 0x14, 0xf1, 0xbf, 0x69, 0xf7, 0xff, 0x00, 0x00,
0x00, 0xff, 0xff, 0x80, 0x0a, 0xbc, 0x80, 0x48, 0x0d, 0x00, 0x00,
// 1192 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0x4d, 0x6f, 0x23, 0x45,
0x13, 0x7e, 0xc7, 0x63, 0x3b, 0x76, 0x79, 0xbd, 0xeb, 0xf4, 0x9b, 0x8d, 0x9c, 0x28, 0xf2, 0x9a,
0x3e, 0x90, 0xb0, 0x12, 0x01, 0x12, 0x09, 0x41, 0x10, 0x12, 0x6c, 0xec, 0xd5, 0x0e, 0x90, 0x64,
0x69, 0x67, 0x17, 0xc1, 0x01, 0xa9, 0x63, 0x37, 0xc9, 0x28, 0xe3, 0x19, 0x33, 0xd3, 0x4e, 0xe2,
0x3d, 0x70, 0x83, 0x03, 0xfc, 0x01, 0xee, 0xfc, 0x19, 0x8e, 0xdc, 0xb8, 0xa2, 0xf0, 0x23, 0x90,
0xb8, 0x80, 0xba, 0xa6, 0x7b, 0x66, 0xfc, 0x15, 0x93, 0xdc, 0xa6, 0xaa, 0xab, 0xaa, 0x9f, 0x7e,
0xea, 0xa3, 0x7b, 0xa0, 0x3a, 0x08, 0xdd, 0x0b, 0x2e, 0xc5, 0xf6, 0x20, 0x0c, 0x64, 0x40, 0x4a,
0xae, 0x2f, 0x45, 0xe8, 0x73, 0x8f, 0x1e, 0x41, 0xd9, 0xf1, 0x7b, 0xe2, 0xea, 0x40, 0x48, 0x4e,
0x9a, 0x50, 0xd9, 0x0f, 0xbc, 0x61, 0xdf, 0xff, 0x8c, 0x9f, 0x08, 0xaf, 0x6e, 0x35, 0xad, 0xad,
0x32, 0xcb, 0xaa, 0x94, 0xc5, 0xb1, 0xdb, 0x17, 0x9f, 0x0f, 0xb9, 0x2f, 0x87, 0xfd, 0x7a, 0x2e,
0xb6, 0xc8, 0xa8, 0xe8, 0xdf, 0x16, 0x94, 0x9f, 0x86, 0xbc, 0x2f, 0x30, 0xe2, 0x3a, 0x94, 0x58,
0x70, 0x99, 0x0d, 0x97, 0xc8, 0xe4, 0x75, 0xb8, 0xef, 0xf8, 0x17, 0x22, 0x8c, 0x44, 0xdb, 0xe7,
0x27, 0x9e, 0xe8, 0x61, 0xb8, 0x12, 0x9b, 0xd0, 0x92, 0x0d, 0x28, 0xef, 0xf3, 0xee, 0x99, 0x38,
0x1e, 0x0d, 0x44, 0xdd, 0xc6, 0x20, 0xa9, 0x22, 0x59, 0xed, 0xb8, 0xaf, 0x44, 0x3d, 0xdf, 0xb4,
0xb6, 0xaa, 0x2c, 0x55, 0x4c, 0xe2, 0x2d, 0x4c, 0xe1, 0x25, 0x14, 0xee, 0x31, 0xee, 0x9f, 0x26,
0x18, 0x8a, 0x88, 0x61, 0x4c, 0x47, 0x36, 0xa1, 0xf8, 0xd4, 0x15, 0x5e, 0x2f, 0xaa, 0x2f, 0x35,
0xed, 0xad, 0xca, 0xce, 0x83, 0x6d, 0xc3, 0xdf, 0x36, 0xea, 0x99, 0x5e, 0xa6, 0x14, 0xee, 0x3b,
0xfd, 0x41, 0x10, 0x4a, 0x26, 0xa2, 0x41, 0xe0, 0x47, 0x82, 0xd4, 0xc0, 0x6e, 0x87, 0xa1, 0x3e,
0xbb, 0xfa, 0xa4, 0xdf, 0x41, 0xed, 0x89, 0x17, 0x74, 0xcf, 0x5b, 0x5c, 0x72, 0x26, 0xbe, 0x1d,
0x8a, 0x48, 0x92, 0x15, 0x28, 0x60, 0x16, 0xb4, 0x5d, 0x2c, 0x28, 0x2d, 0x32, 0xa9, 0x69, 0x8e,
0x05, 0xa5, 0x45, 0x7f, 0xa4, 0x22, 0xcf, 0x62, 0x41, 0x69, 0x3b, 0x9e, 0xdb, 0x8d, 0x29, 0xc8,
0xb3, 0x58, 0x20, 0x04, 0xf2, 0x2f, 0x5d, 0x71, 0xa9, 0xcf, 0x8d, 0xdf, 0xd4, 0x81, 0xe5, 0xcc,
0xfe, 0x1a, 0xe6, 0x2a, 0x14, 0x59, 0x70, 0xe9, 0xb4, 0xa2, 0xba, 0xd5, 0xb4, 0xb7, 0xf2, 0x4c,
0x4b, 0xc8, 0x2e, 0xa6, 0x5f, 0x2d, 0xe5, 0x70, 0x29, 0x55, 0xd0, 0x35, 0x28, 0x20, 0xd5, 0xea,
0x94, 0xa9, 0xaf, 0xfa, 0xa4, 0xff, 0x58, 0x50, 0x3e, 0xe0, 0x57, 0x08, 0x23, 0x22, 0x1f, 0x42,
0xa9, 0x23, 0xb9, 0xdf, 0xe3, 0x61, 0x0f, 0x8d, 0x2a, 0x3b, 0xaf, 0xa5, 0x14, 0x26, 0x66, 0xdb,
0xc6, 0xa6, 0xed, 0xcb, 0x70, 0xc4, 0x12, 0x17, 0xb2, 0x07, 0x4b, 0xba, 0x26, 0x10, 0x43, 0x65,
0xa7, 0x39, 0xcb, 0x3b, 0x29, 0x1b, 0xe5, 0x6c, 0x1c, 0xd6, 0x3f, 0x80, 0xea, 0x58, 0x58, 0x85,
0xf5, 0x5c, 0x8c, 0x4c, 0x46, 0xce, 0xc5, 0x48, 0x71, 0x77, 0xc1, 0xbd, 0x61, 0xcc, 0x73, 0x9e,
0xc5, 0xc2, 0x5e, 0xee, 0x3d, 0x6b, 0x7d, 0x0f, 0xee, 0x65, 0xa3, 0xde, 0xc6, 0x97, 0x7e, 0x0d,
0x64, 0x3f, 0x14, 0x5c, 0x0a, 0x84, 0x77, 0x20, 0xa2, 0x88, 0x9f, 0x8a, 0xf9, 0x99, 0x8e, 0xb3,
0x97, 0xcb, 0x66, 0x6f, 0x03, 0xca, 0x4e, 0x64, 0x0e, 0x6e, 0x63, 0x5d, 0xa6, 0x0a, 0xfa, 0x18,
0x48, 0x4b, 0x78, 0x42, 0x0a, 0xdd, 0xbf, 0x37, 0xc4, 0xa7, 0x1d, 0x83, 0x65, 0xb1, 0x2d, 0xd9,
0x84, 0xbc, 0x6a, 0x5d, 0x84, 0x52, 0xd9, 0xf9, 0x7f, 0xca, 0x74, 0x32, 0x27, 0x18, 0x1a, 0x50,
0xd7, 0x04, 0xd5, 0xed, 0xbe, 0xe0, 0x80, 0x33, 0x4a, 0xd9, 0x6c, 0x65, 0x4f, 0x6e, 0x95, 0x0c,
0x10, 0xbd, 0xd5, 0x47, 0xe6, 0xac, 0x77, 0xdd, 0x8a, 0x7e, 0xa5, 0xb5, 0xaa, 0x25, 0x0e, 0xd5,
0x6a, 0xec, 0x83, 0xdf, 0xf3, 0x8f, 0x3c, 0x81, 0x43, 0xc5, 0x56, 0x3d, 0x14, 0xd5, 0xed, 0xa6,
0xad, 0x62, 0xa3, 0x40, 0x77, 0xa1, 0xd8, 0xe9, 0x9e, 0x89, 0x3e, 0x27, 0x6f, 0xa8, 0x42, 0xed,
0x89, 0x2b, 0x11, 0xe9, 0x32, 0x7f, 0x30, 0x41, 0x1f, 0x33, 0xeb, 0xf4, 0x27, 0x4b, 0xa3, 0x9f,
0x83, 0xa8, 0x88, 0x7b, 0x47, 0xf5, 0xfc, 0xd4, 0xc4, 0x51, 0x7a, 0xa6, 0x97, 0x49, 0x1b, 0x6a,
0x8e, 0x3f, 0x18, 0xca, 0x96, 0xf8, 0xc6, 0xf5, 0x5d, 0xe9, 0x06, 0x7e, 0x54, 0x2f, 0xa2, 0xcb,
0x5a, 0x76, 0xeb, 0x31, 0x0b, 0x36, 0xe5, 0x42, 0x7f, 0xb0, 0xe0, 0xc1, 0x84, 0x72, 0x01, 0xae,
0xdc, 0xcd, 0xb8, 0xde, 0x4d, 0x46, 0xa6, 0x8d, 0x86, 0x8d, 0xb9, 0x68, 0xc6, 0x27, 0xe8, 0x2f,
0x16, 0xac, 0xcc, 0x32, 0x98, 0x89, 0xa6, 0x01, 0xf0, 0x3c, 0x74, 0xfb, 0x3c, 0x1c, 0x7d, 0x2a,
0x46, 0xfa, 0xf6, 0xc8, 0x68, 0xc8, 0x17, 0xb0, 0x3a, 0x11, 0xeb, 0xe3, 0x6e, 0x4c, 0x51, 0x0c,
0xea, 0xd1, 0x5c, 0x50, 0xb1, 0x1d, 0x9b, 0xe3, 0x4e, 0xff, 0xb2, 0xe0, 0xe1, 0xcc, 0xa5, 0xb4,
0xfa, 0xac, 0x6c, 0xa1, 0x3f, 0x86, 0xda, 0x4b, 0x35, 0x18, 0x5a, 0x22, 0x92, 0xae, 0xcf, 0x95,
0xa5, 0x2e, 0xcf, 0x29, 0x3d, 0x71, 0xa0, 0x84, 0xba, 0x03, 0x3e, 0xd0, 0x30, 0xdf, 0x5c, 0x00,
0x73, 0xdb, 0xd8, 0xeb, 0xb9, 0x69, 0x44, 0x05, 0x06, 0xe7, 0xb8, 0xb9, 0x14, 0x50, 0x50, 0x13,
0x71, 0xcc, 0xe1, 0x56, 0x53, 0x2d, 0x80, 0x0d, 0x33, 0x49, 0xc6, 0x90, 0xdc, 0xdc, 0x93, 0xef,
0x03, 0xa4, 0xa6, 0xba, 0xdd, 0x6f, 0xa8, 0xcf, 0x8c, 0x31, 0x7d, 0x06, 0x1b, 0x66, 0xcc, 0xdd,
0x62, 0x43, 0x53, 0x2d, 0xb9, 0xb4, 0x5a, 0x68, 0x1b, 0xec, 0x17, 0xcc, 0x51, 0x57, 0x1d, 0x76,
0xab, 0x49, 0x91, 0x96, 0x94, 0xcb, 0xb3, 0x20, 0x92, 0xc6, 0x45, 0x7d, 0x2b, 0xdd, 0xf3, 0x20,
0x94, 0x88, 0xb8, 0xca, 0xf0, 0x9b, 0x3a, 0x50, 0x3b, 0x0c, 0x7a, 0xa2, 0x23, 0xb9, 0x4c, 0x26,
0xd1, 0x23, 0x0c, 0x8d, 0x01, 0x2b, 0x3b, 0xd5, 0xf4, 0x60, 0x2f, 0x98, 0xc3, 0x70, 0x53, 0x35,
0xe0, 0x95, 0x83, 0x19, 0x4a, 0x28, 0xd0, 0x1f, 0x2d, 0x00, 0x13, 0x6b, 0x18, 0x2d, 0x8e, 0xf2,
0x4e, 0xe6, 0x4e, 0x9d, 0x1e, 0x56, 0xc9, 0x12, 0xcb, 0xdc, 0xbc, 0x5b, 0x66, 0x36, 0x69, 0xd6,
0x6b, 0xa9, 0x7d, 0xac, 0xd7, 0xe7, 0xe7, 0xf4, 0x10, 0xaa, 0xfb, 0xde, 0x30, 0x92, 0x22, 0xd4,
0x70, 0x12, 0xcc, 0x56, 0x06, 0x33, 0xd9, 0x84, 0x25, 0x84, 0x2c, 0xa4, 0x1e, 0x01, 0x13, 0x40,
0xcd, 0x2a, 0xed, 0x40, 0x61, 0x7e, 0xe7, 0x12, 0xc8, 0xe3, 0x73, 0x4e, 0x93, 0x8d, 0x2f, 0xb9,
0x1a, 0xd8, 0x07, 0x6e, 0x5c, 0x1d, 0x36, 0x53, 0x9f, 0xa8, 0xe1, 0x57, 0x58, 0xbd, 0x4a, 0xc3,
0xd5, 0x45, 0xb6, 0x1c, 0x57, 0x83, 0x9a, 0xbc, 0x77, 0xb9, 0x72, 0xcc, 0x8b, 0xc8, 0xce, 0xbc,
0x88, 0x7e, 0xb7, 0x60, 0x99, 0x89, 0xc8, 0x7d, 0x25, 0x1c, 0x3f, 0x92, 0xe1, 0x30, 0xe9, 0xe4,
0x4f, 0x82, 0x13, 0xa7, 0x85, 0x51, 0x6d, 0x16, 0x0b, 0x26, 0x47, 0xb9, 0xb9, 0x39, 0x7a, 0x4b,
0xbd, 0xa1, 0x83, 0xb0, 0xa7, 0xda, 0x39, 0x08, 0x35, 0xeb, 0x13, 0x86, 0x59, 0x0b, 0xf2, 0x36,
0x2c, 0x75, 0x82, 0x61, 0xd8, 0x4d, 0x66, 0xfd, 0x6a, 0x6a, 0x1c, 0xa3, 0x8a, 0x97, 0x99, 0x31,
0xcb, 0xe4, 0xb4, 0xb0, 0x20, 0xa7, 0xdf, 0x5b, 0x70, 0x2f, 0x1b, 0xe3, 0x3f, 0x15, 0x6a, 0xcc,
0x65, 0x6e, 0x26, 0x97, 0xf6, 0x2c, 0x2e, 0xf3, 0x29, 0x97, 0xe9, 0x4b, 0xa6, 0x90, 0x79, 0xc9,
0xd0, 0x33, 0x58, 0x9b, 0x22, 0x78, 0x3f, 0xe8, 0x0f, 0x54, 0x26, 0xef, 0x4a, 0xf4, 0x0a, 0x14,
0xda, 0x61, 0xa8, 0x29, 0x2e, 0xb3, 0x58, 0xa0, 0x5f, 0xc2, 0xc3, 0x8e, 0x90, 0x19, 0x7e, 0x33,
0x2d, 0x7a, 0xe4, 0xf5, 0xe6, 0x9c, 0xfc, 0xc8, 0xeb, 0x29, 0x83, 0x43, 0x71, 0x39, 0x67, 0xc3,
0x43, 0x71, 0x49, 0x77, 0xa1, 0x74, 0x1c, 0x0c, 0x02, 0x2f, 0x38, 0x1d, 0x65, 0xbb, 0xc0, 0xba,
0xa9, 0x0b, 0x9e, 0xd4, 0x7e, 0xbd, 0x6e, 0x58, 0xbf, 0x5d, 0x37, 0xac, 0x3f, 0xae, 0x1b, 0xd6,
0xcf, 0x7f, 0x36, 0xfe, 0x77, 0x52, 0xc4, 0x5f, 0xb0, 0xdd, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff,
0x50, 0x2b, 0xa7, 0xda, 0x93, 0x0d, 0x00, 0x00,
}

View file

@ -121,6 +121,11 @@ message URI {
uint32 Port = 3;
}
message NodeStateMessage {
URI URI = 1;
string State = 2;
}
message NodeStatus {
URI URI = 1;
MaxSlices MaxSlices = 2;

View file

@ -12,11 +12,7 @@ type NopSecurityManager struct {
}
// SetRestricted no-op.
func (sdm *NopSecurityManager) SetRestricted() {
}
func (sdm *NopSecurityManager) SetRestricted() {}
// SetNormal no-op.
func (sdm *NopSecurityManager) SetNormal() {
}
func (sdm *NopSecurityManager) SetNormal() {}

View file

@ -151,28 +151,6 @@ func (s *Server) Open() error {
s.Holder.LogOutput = s.LogOutput
s.Holder.Peek()
// Start the BroadcastReceiver.
if err := s.BroadcastReceiver.Start(s); err != nil {
return fmt.Errorf("starting BroadcastReceiver: %v", err)
}
// Open Cluster management.
if err := s.Cluster.Open(); err != nil {
return fmt.Errorf("opening Cluster: %v", err)
}
// Open holder.
if err := s.Holder.Open(); err != nil {
return fmt.Errorf("opening Holder: %v", err)
}
// Listen for joining nodes.
// This needs to start after the Holder has opened so that nodes can join
// the cluster without waiting for data to load on the coordinator. Before
// this starts, the joins are queued up in the Cluster.joiningURIs buffered
// channel.
s.Cluster.ListenForJoins()
// Create default HTTP client
s.createDefaultClient()
@ -191,6 +169,8 @@ func (s *Server) Open() error {
s.Handler.Executor = e
s.Handler.LogOutput = s.LogOutput
s.Cluster.prefect = s.Handler
// Initialize Holder.
s.Holder.Broadcaster = s.Broadcaster
@ -202,6 +182,29 @@ func (s *Server) Open() error {
}
}()
// Start the BroadcastReceiver.
if err := s.BroadcastReceiver.Start(s); err != nil {
return fmt.Errorf("starting BroadcastReceiver: %v", err)
}
// Open Cluster management.
if err := s.Cluster.Open(); err != nil {
return fmt.Errorf("opening Cluster: %v", err)
}
// Open holder.
if err := s.Holder.Open(); err != nil {
return fmt.Errorf("opening Holder: %v", err)
}
s.Cluster.setNodeState(NodeStateReady)
// Listen for joining nodes.
// This needs to start after the Holder has opened so that nodes can join
// the cluster without waiting for data to load on the coordinator. Before
// this starts, the joins are queued up in the Cluster.joiningURIs buffered
// channel.
s.Cluster.ListenForJoins()
// Start background monitoring.
s.wg.Add(3)
go func() { defer s.wg.Done(); s.monitorAntiEntropy() }()
@ -358,6 +361,11 @@ func (s *Server) ReceiveMessage(pb proto.Message) error {
}
case *internal.SetCoordinatorMessage:
s.Cluster.SetCoordinator(DecodeURI(obj.Old), DecodeURI(obj.New))
case *internal.NodeStateMessage:
err := s.Cluster.ReceiveNodeState(DecodeURI(obj.URI), obj.State)
if err != nil {
return err
}
}
return nil

View file

@ -32,6 +32,8 @@ func NewHandler() *Handler {
// Handler test messages can no-op.
h.Broadcaster = pilosa.NopBroadcaster
h.SetNormal()
return h
}