Vendor dependencies
This commit is contained in:
170
vendor/go.etcd.io/etcd/raft/raftpb/confchange.go
generated
vendored
Normal file
170
vendor/go.etcd.io/etcd/raft/raftpb/confchange.go
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
// Copyright 2019 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package raftpb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
// ConfChangeI abstracts over ConfChangeV2 and (legacy) ConfChange to allow
|
||||
// treating them in a unified manner.
|
||||
type ConfChangeI interface {
|
||||
AsV2() ConfChangeV2
|
||||
AsV1() (ConfChange, bool)
|
||||
}
|
||||
|
||||
// MarshalConfChange calls Marshal on the underlying ConfChange or ConfChangeV2
|
||||
// and returns the result along with the corresponding EntryType.
|
||||
func MarshalConfChange(c ConfChangeI) (EntryType, []byte, error) {
|
||||
var typ EntryType
|
||||
var ccdata []byte
|
||||
var err error
|
||||
if ccv1, ok := c.AsV1(); ok {
|
||||
typ = EntryConfChange
|
||||
ccdata, err = ccv1.Marshal()
|
||||
} else {
|
||||
ccv2 := c.AsV2()
|
||||
typ = EntryConfChangeV2
|
||||
ccdata, err = ccv2.Marshal()
|
||||
}
|
||||
return typ, ccdata, err
|
||||
}
|
||||
|
||||
// AsV2 returns a V2 configuration change carrying out the same operation.
|
||||
func (c ConfChange) AsV2() ConfChangeV2 {
|
||||
return ConfChangeV2{
|
||||
Changes: []ConfChangeSingle{{
|
||||
Type: c.Type,
|
||||
NodeID: c.NodeID,
|
||||
}},
|
||||
Context: c.Context,
|
||||
}
|
||||
}
|
||||
|
||||
// AsV1 returns the ConfChange and true.
|
||||
func (c ConfChange) AsV1() (ConfChange, bool) {
|
||||
return c, true
|
||||
}
|
||||
|
||||
// AsV2 is the identity.
|
||||
func (c ConfChangeV2) AsV2() ConfChangeV2 { return c }
|
||||
|
||||
// AsV1 returns ConfChange{} and false.
|
||||
func (c ConfChangeV2) AsV1() (ConfChange, bool) { return ConfChange{}, false }
|
||||
|
||||
// EnterJoint returns two bools. The second bool is true if and only if this
|
||||
// config change will use Joint Consensus, which is the case if it contains more
|
||||
// than one change or if the use of Joint Consensus was requested explicitly.
|
||||
// The first bool can only be true if second one is, and indicates whether the
|
||||
// Joint State will be left automatically.
|
||||
func (c *ConfChangeV2) EnterJoint() (autoLeave bool, ok bool) {
|
||||
// NB: in theory, more config changes could qualify for the "simple"
|
||||
// protocol but it depends on the config on top of which the changes apply.
|
||||
// For example, adding two learners is not OK if both nodes are part of the
|
||||
// base config (i.e. two voters are turned into learners in the process of
|
||||
// applying the conf change). In practice, these distinctions should not
|
||||
// matter, so we keep it simple and use Joint Consensus liberally.
|
||||
if c.Transition != ConfChangeTransitionAuto || len(c.Changes) > 1 {
|
||||
// Use Joint Consensus.
|
||||
var autoLeave bool
|
||||
switch c.Transition {
|
||||
case ConfChangeTransitionAuto:
|
||||
autoLeave = true
|
||||
case ConfChangeTransitionJointImplicit:
|
||||
autoLeave = true
|
||||
case ConfChangeTransitionJointExplicit:
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown transition: %+v", c))
|
||||
}
|
||||
return autoLeave, true
|
||||
}
|
||||
return false, false
|
||||
}
|
||||
|
||||
// LeaveJoint is true if the configuration change leaves a joint configuration.
|
||||
// This is the case if the ConfChangeV2 is zero, with the possible exception of
|
||||
// the Context field.
|
||||
func (c *ConfChangeV2) LeaveJoint() bool {
|
||||
cpy := *c
|
||||
cpy.Context = nil
|
||||
return proto.Equal(&cpy, &ConfChangeV2{})
|
||||
}
|
||||
|
||||
// ConfChangesFromString parses a Space-delimited sequence of operations into a
|
||||
// slice of ConfChangeSingle. The supported operations are:
|
||||
// - vn: make n a voter,
|
||||
// - ln: make n a learner,
|
||||
// - rn: remove n, and
|
||||
// - un: update n.
|
||||
func ConfChangesFromString(s string) ([]ConfChangeSingle, error) {
|
||||
var ccs []ConfChangeSingle
|
||||
toks := strings.Split(strings.TrimSpace(s), " ")
|
||||
if toks[0] == "" {
|
||||
toks = nil
|
||||
}
|
||||
for _, tok := range toks {
|
||||
if len(tok) < 2 {
|
||||
return nil, fmt.Errorf("unknown token %s", tok)
|
||||
}
|
||||
var cc ConfChangeSingle
|
||||
switch tok[0] {
|
||||
case 'v':
|
||||
cc.Type = ConfChangeAddNode
|
||||
case 'l':
|
||||
cc.Type = ConfChangeAddLearnerNode
|
||||
case 'r':
|
||||
cc.Type = ConfChangeRemoveNode
|
||||
case 'u':
|
||||
cc.Type = ConfChangeUpdateNode
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown input: %s", tok)
|
||||
}
|
||||
id, err := strconv.ParseUint(tok[1:], 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cc.NodeID = id
|
||||
ccs = append(ccs, cc)
|
||||
}
|
||||
return ccs, nil
|
||||
}
|
||||
|
||||
// ConfChangesToString is the inverse to ConfChangesFromString.
|
||||
func ConfChangesToString(ccs []ConfChangeSingle) string {
|
||||
var buf strings.Builder
|
||||
for i, cc := range ccs {
|
||||
if i > 0 {
|
||||
buf.WriteByte(' ')
|
||||
}
|
||||
switch cc.Type {
|
||||
case ConfChangeAddNode:
|
||||
buf.WriteByte('v')
|
||||
case ConfChangeAddLearnerNode:
|
||||
buf.WriteByte('l')
|
||||
case ConfChangeRemoveNode:
|
||||
buf.WriteByte('r')
|
||||
case ConfChangeUpdateNode:
|
||||
buf.WriteByte('u')
|
||||
default:
|
||||
buf.WriteString("unknown")
|
||||
}
|
||||
fmt.Fprintf(&buf, "%d", cc.NodeID)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
45
vendor/go.etcd.io/etcd/raft/raftpb/confstate.go
generated
vendored
Normal file
45
vendor/go.etcd.io/etcd/raft/raftpb/confstate.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2019 The etcd Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package raftpb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Equivalent returns a nil error if the inputs describe the same configuration.
|
||||
// On mismatch, returns a descriptive error showing the differences.
|
||||
func (cs ConfState) Equivalent(cs2 ConfState) error {
|
||||
cs1 := cs
|
||||
orig1, orig2 := cs1, cs2
|
||||
s := func(sl *[]uint64) {
|
||||
*sl = append([]uint64(nil), *sl...)
|
||||
sort.Slice(*sl, func(i, j int) bool { return (*sl)[i] < (*sl)[j] })
|
||||
}
|
||||
|
||||
for _, cs := range []*ConfState{&cs1, &cs2} {
|
||||
s(&cs.Voters)
|
||||
s(&cs.Learners)
|
||||
s(&cs.VotersOutgoing)
|
||||
s(&cs.LearnersNext)
|
||||
cs.XXX_unrecognized = nil
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(cs1, cs2) {
|
||||
return fmt.Errorf("ConfStates not equivalent after sorting:\n%+#v\n%+#v\nInputs were:\n%+#v\n%+#v", cs1, cs2, orig1, orig2)
|
||||
}
|
||||
return nil
|
||||
}
|
2646
vendor/go.etcd.io/etcd/raft/raftpb/raft.pb.go
generated
vendored
Normal file
2646
vendor/go.etcd.io/etcd/raft/raftpb/raft.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
177
vendor/go.etcd.io/etcd/raft/raftpb/raft.proto
generated
vendored
Normal file
177
vendor/go.etcd.io/etcd/raft/raftpb/raft.proto
generated
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
syntax = "proto2";
|
||||
package raftpb;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
|
||||
option (gogoproto.marshaler_all) = true;
|
||||
option (gogoproto.sizer_all) = true;
|
||||
option (gogoproto.unmarshaler_all) = true;
|
||||
option (gogoproto.goproto_getters_all) = false;
|
||||
option (gogoproto.goproto_enum_prefix_all) = false;
|
||||
|
||||
enum EntryType {
|
||||
EntryNormal = 0;
|
||||
EntryConfChange = 1; // corresponds to pb.ConfChange
|
||||
EntryConfChangeV2 = 2; // corresponds to pb.ConfChangeV2
|
||||
}
|
||||
|
||||
message Entry {
|
||||
optional uint64 Term = 2 [(gogoproto.nullable) = false]; // must be 64-bit aligned for atomic operations
|
||||
optional uint64 Index = 3 [(gogoproto.nullable) = false]; // must be 64-bit aligned for atomic operations
|
||||
optional EntryType Type = 1 [(gogoproto.nullable) = false];
|
||||
optional bytes Data = 4;
|
||||
}
|
||||
|
||||
message SnapshotMetadata {
|
||||
optional ConfState conf_state = 1 [(gogoproto.nullable) = false];
|
||||
optional uint64 index = 2 [(gogoproto.nullable) = false];
|
||||
optional uint64 term = 3 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
message Snapshot {
|
||||
optional bytes data = 1;
|
||||
optional SnapshotMetadata metadata = 2 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
enum MessageType {
|
||||
MsgHup = 0;
|
||||
MsgBeat = 1;
|
||||
MsgProp = 2;
|
||||
MsgApp = 3;
|
||||
MsgAppResp = 4;
|
||||
MsgVote = 5;
|
||||
MsgVoteResp = 6;
|
||||
MsgSnap = 7;
|
||||
MsgHeartbeat = 8;
|
||||
MsgHeartbeatResp = 9;
|
||||
MsgUnreachable = 10;
|
||||
MsgSnapStatus = 11;
|
||||
MsgCheckQuorum = 12;
|
||||
MsgTransferLeader = 13;
|
||||
MsgTimeoutNow = 14;
|
||||
MsgReadIndex = 15;
|
||||
MsgReadIndexResp = 16;
|
||||
MsgPreVote = 17;
|
||||
MsgPreVoteResp = 18;
|
||||
}
|
||||
|
||||
message Message {
|
||||
optional MessageType type = 1 [(gogoproto.nullable) = false];
|
||||
optional uint64 to = 2 [(gogoproto.nullable) = false];
|
||||
optional uint64 from = 3 [(gogoproto.nullable) = false];
|
||||
optional uint64 term = 4 [(gogoproto.nullable) = false];
|
||||
optional uint64 logTerm = 5 [(gogoproto.nullable) = false];
|
||||
optional uint64 index = 6 [(gogoproto.nullable) = false];
|
||||
repeated Entry entries = 7 [(gogoproto.nullable) = false];
|
||||
optional uint64 commit = 8 [(gogoproto.nullable) = false];
|
||||
optional Snapshot snapshot = 9 [(gogoproto.nullable) = false];
|
||||
optional bool reject = 10 [(gogoproto.nullable) = false];
|
||||
optional uint64 rejectHint = 11 [(gogoproto.nullable) = false];
|
||||
optional bytes context = 12;
|
||||
}
|
||||
|
||||
message HardState {
|
||||
optional uint64 term = 1 [(gogoproto.nullable) = false];
|
||||
optional uint64 vote = 2 [(gogoproto.nullable) = false];
|
||||
optional uint64 commit = 3 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
// ConfChangeTransition specifies the behavior of a configuration change with
|
||||
// respect to joint consensus.
|
||||
enum ConfChangeTransition {
|
||||
// Automatically use the simple protocol if possible, otherwise fall back
|
||||
// to ConfChangeJointImplicit. Most applications will want to use this.
|
||||
ConfChangeTransitionAuto = 0;
|
||||
// Use joint consensus unconditionally, and transition out of them
|
||||
// automatically (by proposing a zero configuration change).
|
||||
//
|
||||
// This option is suitable for applications that want to minimize the time
|
||||
// spent in the joint configuration and do not store the joint configuration
|
||||
// in the state machine (outside of InitialState).
|
||||
ConfChangeTransitionJointImplicit = 1;
|
||||
// Use joint consensus and remain in the joint configuration until the
|
||||
// application proposes a no-op configuration change. This is suitable for
|
||||
// applications that want to explicitly control the transitions, for example
|
||||
// to use a custom payload (via the Context field).
|
||||
ConfChangeTransitionJointExplicit = 2;
|
||||
}
|
||||
|
||||
message ConfState {
|
||||
// The voters in the incoming config. (If the configuration is not joint,
|
||||
// then the outgoing config is empty).
|
||||
repeated uint64 voters = 1;
|
||||
// The learners in the incoming config.
|
||||
repeated uint64 learners = 2;
|
||||
// The voters in the outgoing config.
|
||||
repeated uint64 voters_outgoing = 3;
|
||||
// The nodes that will become learners when the outgoing config is removed.
|
||||
// These nodes are necessarily currently in nodes_joint (or they would have
|
||||
// been added to the incoming config right away).
|
||||
repeated uint64 learners_next = 4;
|
||||
// If set, the config is joint and Raft will automatically transition into
|
||||
// the final config (i.e. remove the outgoing config) when this is safe.
|
||||
optional bool auto_leave = 5 [(gogoproto.nullable) = false];
|
||||
}
|
||||
|
||||
enum ConfChangeType {
|
||||
ConfChangeAddNode = 0;
|
||||
ConfChangeRemoveNode = 1;
|
||||
ConfChangeUpdateNode = 2;
|
||||
ConfChangeAddLearnerNode = 3;
|
||||
}
|
||||
|
||||
message ConfChange {
|
||||
optional ConfChangeType type = 2 [(gogoproto.nullable) = false];
|
||||
optional uint64 node_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "NodeID" ];
|
||||
optional bytes context = 4;
|
||||
|
||||
// NB: this is used only by etcd to thread through a unique identifier.
|
||||
// Ideally it should really use the Context instead. No counterpart to
|
||||
// this field exists in ConfChangeV2.
|
||||
optional uint64 id = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "ID" ];
|
||||
}
|
||||
|
||||
// ConfChangeSingle is an individual configuration change operation. Multiple
|
||||
// such operations can be carried out atomically via a ConfChangeV2.
|
||||
message ConfChangeSingle {
|
||||
optional ConfChangeType type = 1 [(gogoproto.nullable) = false];
|
||||
optional uint64 node_id = 2 [(gogoproto.nullable) = false, (gogoproto.customname) = "NodeID"];
|
||||
}
|
||||
|
||||
// ConfChangeV2 messages initiate configuration changes. They support both the
|
||||
// simple "one at a time" membership change protocol and full Joint Consensus
|
||||
// allowing for arbitrary changes in membership.
|
||||
//
|
||||
// The supplied context is treated as an opaque payload and can be used to
|
||||
// attach an action on the state machine to the application of the config change
|
||||
// proposal. Note that contrary to Joint Consensus as outlined in the Raft
|
||||
// paper[1], configuration changes become active when they are *applied* to the
|
||||
// state machine (not when they are appended to the log).
|
||||
//
|
||||
// The simple protocol can be used whenever only a single change is made.
|
||||
//
|
||||
// Non-simple changes require the use of Joint Consensus, for which two
|
||||
// configuration changes are run. The first configuration change specifies the
|
||||
// desired changes and transitions the Raft group into the joint configuration,
|
||||
// in which quorum requires a majority of both the pre-changes and post-changes
|
||||
// configuration. Joint Consensus avoids entering fragile intermediate
|
||||
// configurations that could compromise survivability. For example, without the
|
||||
// use of Joint Consensus and running across three availability zones with a
|
||||
// replication factor of three, it is not possible to replace a voter without
|
||||
// entering an intermediate configuration that does not survive the outage of
|
||||
// one availability zone.
|
||||
//
|
||||
// The provided ConfChangeTransition specifies how (and whether) Joint Consensus
|
||||
// is used, and assigns the task of leaving the joint configuration either to
|
||||
// Raft or the application. Leaving the joint configuration is accomplished by
|
||||
// proposing a ConfChangeV2 with only and optionally the Context field
|
||||
// populated.
|
||||
//
|
||||
// For details on Raft membership changes, see:
|
||||
//
|
||||
// [1]: https://github.com/ongardie/dissertation/blob/master/online-trim.pdf
|
||||
message ConfChangeV2 {
|
||||
optional ConfChangeTransition transition = 1 [(gogoproto.nullable) = false];
|
||||
repeated ConfChangeSingle changes = 2 [(gogoproto.nullable) = false];
|
||||
optional bytes context = 3;
|
||||
}
|
Reference in New Issue
Block a user