Refactor configuration into main.

pull/903/head
Ben Johnson 2014-10-20 23:32:47 -06:00
parent f6ef96c142
commit ccb0e6b6a1
60 changed files with 478 additions and 11622 deletions

2
.gitignore vendored
View File

@ -21,7 +21,7 @@ a.out
.DS_Store
# ignore generated files.
daemon/version.go
cmd/influxd/version.go
parser/lex.yy.c
parser/y.tab.h
parser/y.tab.c

View File

@ -317,9 +317,9 @@ files = $(binary_package) $(debian_package) $(rpm_package) $(source_package)
sha1 = $(shell sh -c "git rev-list --max-count=1 --abbrev-commit HEAD")
build_version_string:
@echo "package main" > daemon/version.go
@echo "const version = \"$(version)\"" >> daemon/version.go
@echo "const gitSha = \"$(sha1)\"" >> daemon/version.go
@echo "package main" > cmd/influxd/version.go
@echo "const version = \"$(version)\"" >> cmd/influxd/version.go
@echo "const gitSha = \"$(sha1)\"" >> cmd/influxd/version.go
package_version_string: build_version_string
sed -i.bak -e "s/REPLACE_VERSION/$(version)/" scripts/post_install.sh

View File

@ -1,25 +0,0 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
coverage.html
coverprofile.out

View File

@ -1,20 +0,0 @@
Copyright 2013 go-raft contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,17 +0,0 @@
COVERPROFILE=cover.out
default: test
cover:
go test -coverprofile=$(COVERPROFILE) .
go tool cover -html=$(COVERPROFILE)
rm $(COVERPROFILE)
dependencies:
go get -d .
test:
go test -i ./...
go test -v ./...
.PHONY: coverage dependencies test

View File

@ -1,138 +0,0 @@
go-raft [![Build Status](https://drone.io/github.com/goraft/raft/status.png)](https://drone.io/github.com/goraft/raft/latest) [![Coverage Status](https://coveralls.io/repos/goraft/raft/badge.png?branch=master)](https://coveralls.io/r/goraft/raft?branch=master)
=======
## Overview
This is a Go implementation of the Raft distributed consensus protocol.
Raft is a protocol by which a cluster of nodes can maintain a replicated state machine.
The state machine is kept in sync through the use of a replicated log.
For more details on Raft, you can read [In Search of an Understandable Consensus Algorithm][raft-paper] by Diego Ongaro and John Ousterhout.
## Project Status
This library is feature complete but should be considered experimental until it has seen more usage.
If you have any questions on implementing go-raft in your project please file an issue.
There is an [active community][community] of developers who can help.
go-raft is under the MIT license.
[community]: https://github.com/goraft/raft/contributors
### Features
- Leader election
- Log replication
- Configuration changes
- Log compaction
- Unit tests
- Fast Protobuf Log Encoding
- HTTP transport
### Projects
These projects are built on go-raft:
- [coreos/etcd](https://github.com/coreos/etcd) - A highly-available key value store for shared configuration and service discovery.
- [goraft/raftd](https://github.com/goraft/raftd) - A reference implementation for using the go-raft library for distributed consensus.
- [skynetservices/skydns](https://github.com/skynetservices/skydns) - DNS for skynet or any other service discovery.
- [influxdb/influxdb](https://github.com/influxdb/influxdb) - An open-source, distributed, time series, events, and metrics database.
- [Weed File System](https://weed-fs.googlecode.com) - A scalable distributed key-to-file system with O(1) disk access for each read.
If you have a project that you're using go-raft in, please add it to this README so others can see implementation examples.
## Contact and Resources
- [raft-dev][raft-dev] is a mailing list for discussion about best practices
and implementation of Raft. Not goraft specific but helpful if you have
questions.
- [Slides from Ben's talk][bens-talk] which includes easy to understand
diagrams of leader election and replication
- The [Raft Consensus homepage][raft-home] has links to additional raft
implementations, slides to talks on Raft and general information
[raft-home]: http://raftconsensus.github.io/
[raft-dev]: https://groups.google.com/forum/#!forum/raft-dev
[bens-talk]: https://speakerdeck.com/benbjohnson/raft-the-understandable-distributed-consensus-protocol
## The Raft Protocol
This section provides a summary of the Raft protocol from a high level.
For a more detailed explanation on the failover process and election terms please see the full paper describing the protocol: [In Search of an Understandable Consensus Algorithm][raft-paper].
### Overview
Maintaining state in a single process on a single server is easy.
Your process is a single point of authority so there are no conflicts when reading and writing state.
Even multi-threaded processes can rely on locks or coroutines to serialize access to the data.
However, in a distributed system there is no single point of authority.
Servers can crash or the network between two machines can become unavailable or any number of other problems can occur.
A distributed consensus protocol is used for maintaining a consistent state across multiple servers in a cluster.
Many distributed systems are built upon the Paxos protocol but Paxos can be difficult to understand and there are many gaps between Paxos and real world implementation.
An alternative is the [Raft distributed consensus protocol][raft-paper] by Diego Ongaro and John Ousterhout.
Raft is a protocol built with understandability as a primary tenet and it centers around two things:
1. Leader Election
2. Replicated Log
With these two constructs, you can build a system that can maintain state across multiple servers -- even in the event of multiple failures.
### Leader Election
The Raft protocol effectively works as a master-slave system whereby state changes are written to a single server in the cluster and are distributed out to the rest of the servers in the cluster.
This simplifies the protocol since there is only one data authority and conflicts will not have to be resolved.
Raft ensures that there is only one leader at a time.
It does this by performing elections among the nodes in the cluster and requiring that a node must receive a majority of the votes in order to become leader.
For example, if you have 3 nodes in your cluster then a single node would need 2 votes in order to become the leader.
For a 5 node cluster, a server would need 3 votes to become leader.
### Replicated Log
To maintain state, a log of commands is maintained.
Each command makes a change to the state of the server and the command is deterministic.
By ensuring that this log is replicated identically between all the nodes in the cluster we can replicate the state at any point in time in the log by running each command sequentially.
Replicating the log under normal conditions is done by sending an `AppendEntries` RPC from the leader to each of the other servers in the cluster (called Peers).
Each peer will append the entries from the leader through a 2-phase commit process which ensure that a majority of servers in the cluster have entries written to log.
## Raft in Practice
### Optimal Cluster Size
The primary consideration when choosing the node count in your Raft cluster is the number of nodes that can simultaneously fail.
Because Raft requires a majority of nodes to be available to make progress, the number of node failures the cluster can tolerate is `(n / 2) - 1`.
This means that a 3-node cluster can tolerate 1 node failure.
If 2 nodes fail then the cluster cannot commit entries or elect a new leader so progress stops.
A 5-node cluster can tolerate 2 node failures. A 9-node cluster can tolerate 4 node failures.
It is unlikely that 4 nodes will simultaneously fail so clusters larger than 9 nodes are not common.
Another consideration is performance.
The leader must replicate log entries for each follower node so CPU and networking resources can quickly be bottlenecked under stress in a large cluster.
### Scaling Raft
Once you grow beyond the maximum size of your cluster there are a few options for scaling Raft:
1. *Core nodes with dumb replication.*
This option requires you to maintain a small cluster (e.g. 5 nodes) that is involved in the Raft process and then replicate only committed log entries to the remaining nodes in the cluster.
This works well if you have reads in your system that can be stale.
2. *Sharding.*
This option requires that you segment your data into different clusters.
This option works well if you need very strong consistency and therefore need to read and write heavily from the leader.
If you have a very large cluster that you need to replicate to using Option 1 then you may want to look at performing hierarchical replication so that nodes can better share the load.
## History
Ben Johnson started this library for use in his behavioral analytics database called [Sky](https://github.com/skydb/sky).
He put it under the MIT license in the hopes that it would be useful for other projects too.
[raft-paper]: https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf

View File

@ -1,146 +0,0 @@
package raft
import (
"io"
"io/ioutil"
"code.google.com/p/gogoprotobuf/proto"
"github.com/influxdb/influxdb/_vendor/raft/protobuf"
)
// The request sent to a server to append entries to the log.
type AppendEntriesRequest struct {
Term uint64
PrevLogIndex uint64
PrevLogTerm uint64
CommitIndex uint64
LeaderName string
Entries []*protobuf.LogEntry
}
// The response returned from a server appending entries to the log.
type AppendEntriesResponse struct {
pb *protobuf.AppendEntriesResponse
peer string
append bool
}
// Creates a new AppendEntries request.
func newAppendEntriesRequest(term uint64, prevLogIndex uint64, prevLogTerm uint64,
commitIndex uint64, leaderName string, entries []*LogEntry) *AppendEntriesRequest {
pbEntries := make([]*protobuf.LogEntry, len(entries))
for i := range entries {
pbEntries[i] = entries[i].pb
}
return &AppendEntriesRequest{
Term: term,
PrevLogIndex: prevLogIndex,
PrevLogTerm: prevLogTerm,
CommitIndex: commitIndex,
LeaderName: leaderName,
Entries: pbEntries,
}
}
// Encodes the AppendEntriesRequest to a buffer. Returns the number of bytes
// written and any error that may have occurred.
func (req *AppendEntriesRequest) Encode(w io.Writer) (int, error) {
pb := &protobuf.AppendEntriesRequest{
Term: proto.Uint64(req.Term),
PrevLogIndex: proto.Uint64(req.PrevLogIndex),
PrevLogTerm: proto.Uint64(req.PrevLogTerm),
CommitIndex: proto.Uint64(req.CommitIndex),
LeaderName: proto.String(req.LeaderName),
Entries: req.Entries,
}
p, err := proto.Marshal(pb)
if err != nil {
return -1, err
}
return w.Write(p)
}
// Decodes the AppendEntriesRequest from a buffer. Returns the number of bytes read and
// any error that occurs.
func (req *AppendEntriesRequest) Decode(r io.Reader) (int, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return -1, err
}
pb := new(protobuf.AppendEntriesRequest)
if err := proto.Unmarshal(data, pb); err != nil {
return -1, err
}
req.Term = pb.GetTerm()
req.PrevLogIndex = pb.GetPrevLogIndex()
req.PrevLogTerm = pb.GetPrevLogTerm()
req.CommitIndex = pb.GetCommitIndex()
req.LeaderName = pb.GetLeaderName()
req.Entries = pb.GetEntries()
return len(data), nil
}
// Creates a new AppendEntries response.
func newAppendEntriesResponse(term uint64, success bool, index uint64, commitIndex uint64) *AppendEntriesResponse {
pb := &protobuf.AppendEntriesResponse{
Term: proto.Uint64(term),
Index: proto.Uint64(index),
Success: proto.Bool(success),
CommitIndex: proto.Uint64(commitIndex),
}
return &AppendEntriesResponse{
pb: pb,
}
}
func (aer *AppendEntriesResponse) Index() uint64 {
return aer.pb.GetIndex()
}
func (aer *AppendEntriesResponse) CommitIndex() uint64 {
return aer.pb.GetCommitIndex()
}
func (aer *AppendEntriesResponse) Term() uint64 {
return aer.pb.GetTerm()
}
func (aer *AppendEntriesResponse) Success() bool {
return aer.pb.GetSuccess()
}
// Encodes the AppendEntriesResponse to a buffer. Returns the number of bytes
// written and any error that may have occurred.
func (resp *AppendEntriesResponse) Encode(w io.Writer) (int, error) {
b, err := proto.Marshal(resp.pb)
if err != nil {
return -1, err
}
return w.Write(b)
}
// Decodes the AppendEntriesResponse from a buffer. Returns the number of bytes read and
// any error that occurs.
func (resp *AppendEntriesResponse) Decode(r io.Reader) (int, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return -1, err
}
resp.pb = new(protobuf.AppendEntriesResponse)
if err := proto.Unmarshal(data, resp.pb); err != nil {
return -1, err
}
return len(data), nil
}

View File

@ -1,68 +0,0 @@
package raft
import (
"bytes"
"testing"
)
func BenchmarkAppendEntriesRequestEncoding(b *testing.B) {
req, tmp := createTestAppendEntriesRequest(2000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
var buf bytes.Buffer
req.Encode(&buf)
}
b.SetBytes(int64(len(tmp)))
}
func BenchmarkAppendEntriesRequestDecoding(b *testing.B) {
req, buf := createTestAppendEntriesRequest(2000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
req.Decode(bytes.NewReader(buf))
}
b.SetBytes(int64(len(buf)))
}
func BenchmarkAppendEntriesResponseEncoding(b *testing.B) {
req, tmp := createTestAppendEntriesResponse(2000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
var buf bytes.Buffer
req.Encode(&buf)
}
b.SetBytes(int64(len(tmp)))
}
func BenchmarkAppendEntriesResponseDecoding(b *testing.B) {
req, buf := createTestAppendEntriesResponse(2000)
b.ResetTimer()
for i := 0; i < b.N; i++ {
req.Decode(bytes.NewReader(buf))
}
b.SetBytes(int64(len(buf)))
}
func createTestAppendEntriesRequest(entryCount int) (*AppendEntriesRequest, []byte) {
entries := make([]*LogEntry, 0)
for i := 0; i < entryCount; i++ {
command := &DefaultJoinCommand{Name: "localhost:1000"}
entry, _ := newLogEntry(nil, nil, 1, 2, command)
entries = append(entries, entry)
}
req := newAppendEntriesRequest(1, 1, 1, 1, "leader", entries)
var buf bytes.Buffer
req.Encode(&buf)
return req, buf.Bytes()
}
func createTestAppendEntriesResponse(entryCount int) (*AppendEntriesResponse, []byte) {
resp := newAppendEntriesResponse(1, true, 1, 1)
var buf bytes.Buffer
resp.Encode(&buf)
return resp, buf.Bytes()
}

View File

@ -1,76 +0,0 @@
package raft
import (
"bytes"
"encoding/json"
"fmt"
"io"
"reflect"
)
var commandTypes map[string]Command
func init() {
commandTypes = map[string]Command{}
}
// Command represents an action to be taken on the replicated state machine.
type Command interface {
CommandName() string
}
// CommandApply represents the interface to apply a command to the server.
type CommandApply interface {
Apply(Context) (interface{}, error)
}
// deprecatedCommandApply represents the old interface to apply a command to the server.
type deprecatedCommandApply interface {
Apply(Server) (interface{}, error)
}
type CommandEncoder interface {
Encode(w io.Writer) error
Decode(r io.Reader) error
}
// Creates a new instance of a command by name.
func newCommand(name string, data []byte) (Command, error) {
// Find the registered command.
command := commandTypes[name]
if command == nil {
return nil, fmt.Errorf("raft.Command: Unregistered command type: %s", name)
}
// Make a copy of the command.
v := reflect.New(reflect.Indirect(reflect.ValueOf(command)).Type()).Interface()
copy, ok := v.(Command)
if !ok {
panic(fmt.Sprintf("raft: Unable to copy command: %s (%v)", command.CommandName(), reflect.ValueOf(v).Kind().String()))
}
// If data for the command was passed in the decode it.
if data != nil {
if encoder, ok := copy.(CommandEncoder); ok {
if err := encoder.Decode(bytes.NewReader(data)); err != nil {
return nil, err
}
} else {
if err := json.NewDecoder(bytes.NewReader(data)).Decode(copy); err != nil {
return nil, err
}
}
}
return copy, nil
}
// Registers a command by storing a reference to an instance of it.
func RegisterCommand(command Command) {
if command == nil {
panic(fmt.Sprintf("raft: Cannot register nil"))
} else if commandTypes[command.CommandName()] != nil {
panic(fmt.Sprintf("raft: Duplicate registration: %s", command.CommandName()))
}
commandTypes[command.CommandName()] = command
}

View File

@ -1,78 +0,0 @@
package raft
import (
"io"
)
// Join command interface
type JoinCommand interface {
Command
NodeName() string
}
// Join command
type DefaultJoinCommand struct {
Name string `json:"name"`
ConnectionString string `json:"connectionString"`
}
// Leave command interface
type LeaveCommand interface {
Command
NodeName() string
}
// Leave command
type DefaultLeaveCommand struct {
Name string `json:"name"`
}
// NOP command
type NOPCommand struct {
}
// The name of the Join command in the log
func (c *DefaultJoinCommand) CommandName() string {
return "raft:join"
}
func (c *DefaultJoinCommand) Apply(server Server) (interface{}, error) {
err := server.AddPeer(c.Name, c.ConnectionString)
return []byte("join"), err
}
func (c *DefaultJoinCommand) NodeName() string {
return c.Name
}
// The name of the Leave command in the log
func (c *DefaultLeaveCommand) CommandName() string {
return "raft:leave"
}
func (c *DefaultLeaveCommand) Apply(server Server) (interface{}, error) {
err := server.RemovePeer(c.Name)
return []byte("leave"), err
}
func (c *DefaultLeaveCommand) NodeName() string {
return c.Name
}
// The name of the NOP command in the log
func (c NOPCommand) CommandName() string {
return "raft:nop"
}
func (c NOPCommand) Apply(server Server) (interface{}, error) {
return nil, nil
}
func (c NOPCommand) Encode(w io.Writer) error {
return nil
}
func (c NOPCommand) Decode(r io.Reader) error {
return nil
}

View File

@ -1,7 +0,0 @@
package raft
type Config struct {
CommitIndex uint64 `json:"commitIndex"`
// TODO decide what we need to store in peer struct
Peers []*Peer `json:"peers"`
}

View File

@ -1,39 +0,0 @@
package raft
// Context represents the current state of the server. It is passed into
// a command when the command is being applied since the server methods
// are locked.
type Context interface {
Server() Server
CurrentTerm() uint64
CurrentIndex() uint64
CommitIndex() uint64
}
// context is the concrete implementation of Context.
type context struct {
server Server
currentIndex uint64
currentTerm uint64
commitIndex uint64
}
// Server returns a reference to the server.
func (c *context) Server() Server {
return c.server
}
// CurrentTerm returns current term the server is in.
func (c *context) CurrentTerm() uint64 {
return c.currentTerm
}
// CurrentIndex returns current index the server is at.
func (c *context) CurrentIndex() uint64 {
return c.currentIndex
}
// CommitIndex returns last commit index the server is at.
func (c *context) CommitIndex() uint64 {
return c.commitIndex
}

View File

@ -1,116 +0,0 @@
package raft
import (
"log"
"os"
)
//------------------------------------------------------------------------------
//
// Variables
//
//------------------------------------------------------------------------------
const (
Debug = 1
Trace = 2
)
var logLevel int = 0
var logger *log.Logger
func init() {
logger = log.New(os.Stdout, "[raft]", log.Lmicroseconds)
}
//------------------------------------------------------------------------------
//
// Functions
//
//------------------------------------------------------------------------------
func LogLevel() int {
return logLevel
}
func SetLogLevel(level int) {
logLevel = level
}
//--------------------------------------
// Warnings
//--------------------------------------
// Prints to the standard logger. Arguments are handled in the manner of
// fmt.Print.
func warn(v ...interface{}) {
logger.Print(v...)
}
// Prints to the standard logger. Arguments are handled in the manner of
// fmt.Printf.
func warnf(format string, v ...interface{}) {
logger.Printf(format, v...)
}
// Prints to the standard logger. Arguments are handled in the manner of
// fmt.Println.
func warnln(v ...interface{}) {
logger.Println(v...)
}
//--------------------------------------
// Basic debugging
//--------------------------------------
// Prints to the standard logger if debug mode is enabled. Arguments
// are handled in the manner of fmt.Print.
func debug(v ...interface{}) {
if logLevel >= Debug {
logger.Print(v...)
}
}
// Prints to the standard logger if debug mode is enabled. Arguments
// are handled in the manner of fmt.Printf.
func debugf(format string, v ...interface{}) {
if logLevel >= Debug {
logger.Printf(format, v...)
}
}
// Prints to the standard logger if debug mode is enabled. Arguments
// are handled in the manner of fmt.Println.
func debugln(v ...interface{}) {
if logLevel >= Debug {
logger.Println(v...)
}
}
//--------------------------------------
// Trace-level debugging
//--------------------------------------
// Prints to the standard logger if trace debugging is enabled. Arguments
// are handled in the manner of fmt.Print.
func trace(v ...interface{}) {
if logLevel >= Trace {
logger.Print(v...)
}
}
// Prints to the standard logger if trace debugging is enabled. Arguments
// are handled in the manner of fmt.Printf.
func tracef(format string, v ...interface{}) {
if logLevel >= Trace {
logger.Printf(format, v...)
}
}
// Prints to the standard logger if trace debugging is enabled. Arguments
// are handled in the manner of debugln.
func traceln(v ...interface{}) {
if logLevel >= Trace {
logger.Println(v...)
}
}

View File

@ -1,61 +0,0 @@
package raft
const (
StateChangeEventType = "stateChange"
LeaderChangeEventType = "leaderChange"
TermChangeEventType = "termChange"
CommitEventType = "commit"
AddPeerEventType = "addPeer"
RemovePeerEventType = "removePeer"
HeartbeatIntervalEventType = "heartbeatInterval"
ElectionTimeoutThresholdEventType = "electionTimeoutThreshold"
HeartbeatEventType = "heartbeat"
)
// Event represents an action that occurred within the Raft library.
// Listeners can subscribe to event types by using the Server.AddEventListener() function.
type Event interface {
Type() string
Source() interface{}
Value() interface{}
PrevValue() interface{}
}
// event is the concrete implementation of the Event interface.
type event struct {
typ string
source interface{}
value interface{}
prevValue interface{}
}
// newEvent creates a new event.
func newEvent(typ string, value interface{}, prevValue interface{}) *event {
return &event{
typ: typ,
value: value,
prevValue: prevValue,
}
}
// Type returns the type of event that occurred.
func (e *event) Type() string {
return e.typ
}
// Source returns the object that dispatched the event.
func (e *event) Source() interface{} {
return e.source
}
// Value returns the current value associated with the event, if applicable.
func (e *event) Value() interface{} {
return e.value
}
// PrevValue returns the previous value associated with the event, if applicable.
func (e *event) PrevValue() interface{} {
return e.prevValue
}

View File

@ -1,68 +0,0 @@
package raft
import (
"reflect"
"sync"
)
// eventDispatcher is responsible for managing listeners for named events
// and dispatching event notifications to those listeners.
type eventDispatcher struct {
sync.RWMutex
source interface{}
listeners map[string]eventListeners
}
// EventListener is a function that can receive event notifications.
type EventListener func(Event)
// EventListeners represents a collection of individual listeners.
type eventListeners []EventListener
// newEventDispatcher creates a new eventDispatcher instance.
func newEventDispatcher(source interface{}) *eventDispatcher {
return &eventDispatcher{
source: source,
listeners: make(map[string]eventListeners),
}
}
// AddEventListener adds a listener function for a given event type.
func (d *eventDispatcher) AddEventListener(typ string, listener EventListener) {
d.Lock()
defer d.Unlock()
d.listeners[typ] = append(d.listeners[typ], listener)
}
// RemoveEventListener removes a listener function for a given event type.
func (d *eventDispatcher) RemoveEventListener(typ string, listener EventListener) {
d.Lock()
defer d.Unlock()
// Grab a reference to the function pointer once.
ptr := reflect.ValueOf(listener).Pointer()
// Find listener by pointer and remove it.
listeners := d.listeners[typ]
for i, l := range listeners {
if reflect.ValueOf(l).Pointer() == ptr {
d.listeners[typ] = append(listeners[:i], listeners[i+1:]...)
}
}
}
// DispatchEvent dispatches an event.
func (d *eventDispatcher) DispatchEvent(e Event) {
d.RLock()
defer d.RUnlock()
// Automatically set the event source.
if e, ok := e.(*event); ok {
e.source = d.source
}
// Dispatch the event to all listeners.
for _, l := range d.listeners[e.Type()] {
l(e)
}
}

View File

@ -1,64 +0,0 @@
package raft
import (
"testing"
"github.com/stretchr/testify/assert"
)
// Ensure that we can listen and dispatch events.
func TestDispatchEvent(t *testing.T) {
var count int
dispatcher := newEventDispatcher(nil)
dispatcher.AddEventListener("foo", func(e Event) {
count += 1
})
dispatcher.AddEventListener("foo", func(e Event) {
count += 10
})
dispatcher.AddEventListener("bar", func(e Event) {
count += 100
})
dispatcher.DispatchEvent(&event{typ: "foo", value: nil, prevValue: nil})
assert.Equal(t, 11, count)
}
// Ensure that we can add and remove a listener.
func TestRemoveEventListener(t *testing.T) {
var count int
f0 := func(e Event) {
count += 1
}
f1 := func(e Event) {
count += 10
}
dispatcher := newEventDispatcher(nil)
dispatcher.AddEventListener("foo", f0)
dispatcher.AddEventListener("foo", f1)
dispatcher.DispatchEvent(&event{typ: "foo"})
dispatcher.RemoveEventListener("foo", f0)
dispatcher.DispatchEvent(&event{typ: "foo"})
assert.Equal(t, 21, count)
}
// Ensure that event is properly passed to listener.
func TestEventListener(t *testing.T) {
dispatcher := newEventDispatcher("X")
dispatcher.AddEventListener("foo", func(e Event) {
assert.Equal(t, "foo", e.Type())
assert.Equal(t, "X", e.Source())
assert.Equal(t, 10, e.Value())
assert.Equal(t, 20, e.PrevValue())
})
dispatcher.DispatchEvent(&event{typ: "foo", value: 10, prevValue: 20})
}
// Benchmark the performance of event dispatch.
func BenchmarkEventDispatch(b *testing.B) {
dispatcher := newEventDispatcher(nil)
dispatcher.AddEventListener("xxx", func(e Event) {})
for i := 0; i < b.N; i++ {
dispatcher.DispatchEvent(&event{typ: "foo", value: 10, prevValue: 20})
}
}

View File

@ -1,325 +0,0 @@
package raft
import (
"bytes"
"fmt"
"io"
"net/http"
"net/url"
"path"
"time"
)
// Parts from this transporter were heavily influenced by Peter Bougon's
// raft implementation: https://github.com/peterbourgon/raft
//------------------------------------------------------------------------------
//
// Typedefs
//
//------------------------------------------------------------------------------
// An HTTPTransporter is a default transport layer used to communicate between
// multiple servers.
type HTTPTransporter struct {
DisableKeepAlives bool
prefix string
appendEntriesPath string
requestVotePath string
snapshotPath string
snapshotRecoveryPath string
httpClient http.Client
Transport *http.Transport
}
type HTTPMuxer interface {
HandleFunc(string, func(http.ResponseWriter, *http.Request))
}
//------------------------------------------------------------------------------
//
// Constructor
//
//------------------------------------------------------------------------------
// Creates a new HTTP transporter with the given path prefix.
func NewHTTPTransporter(prefix string, timeout time.Duration) *HTTPTransporter {
t := &HTTPTransporter{
DisableKeepAlives: false,
prefix: prefix,
appendEntriesPath: joinPath(prefix, "/appendEntries"),
requestVotePath: joinPath(prefix, "/requestVote"),
snapshotPath: joinPath(prefix, "/snapshot"),
snapshotRecoveryPath: joinPath(prefix, "/snapshotRecovery"),
Transport: &http.Transport{DisableKeepAlives: false},
}
t.httpClient.Transport = t.Transport
t.Transport.ResponseHeaderTimeout = timeout
return t
}
//------------------------------------------------------------------------------
//
// Accessors
//
//------------------------------------------------------------------------------
// Retrieves the path prefix used by the transporter.
func (t *HTTPTransporter) Prefix() string {
return t.prefix
}
// Retrieves the AppendEntries path.
func (t *HTTPTransporter) AppendEntriesPath() string {
return t.appendEntriesPath
}
// Retrieves the RequestVote path.
func (t *HTTPTransporter) RequestVotePath() string {
return t.requestVotePath
}
// Retrieves the Snapshot path.
func (t *HTTPTransporter) SnapshotPath() string {
return t.snapshotPath
}
// Retrieves the SnapshotRecovery path.
func (t *HTTPTransporter) SnapshotRecoveryPath() string {
return t.snapshotRecoveryPath
}
//------------------------------------------------------------------------------
//
// Methods
//
//------------------------------------------------------------------------------
//--------------------------------------
// Installation
//--------------------------------------
// Applies Raft routes to an HTTP router for a given server.
func (t *HTTPTransporter) Install(server Server, mux HTTPMuxer) {
mux.HandleFunc(t.AppendEntriesPath(), t.appendEntriesHandler(server))
mux.HandleFunc(t.RequestVotePath(), t.requestVoteHandler(server))
mux.HandleFunc(t.SnapshotPath(), t.snapshotHandler(server))
mux.HandleFunc(t.SnapshotRecoveryPath(), t.snapshotRecoveryHandler(server))
}
//--------------------------------------
// Outgoing
//--------------------------------------
// Sends an AppendEntries RPC to a peer.
func (t *HTTPTransporter) SendAppendEntriesRequest(server Server, peer *Peer, req *AppendEntriesRequest) *AppendEntriesResponse {
var b bytes.Buffer
if _, err := req.Encode(&b); err != nil {
traceln("transporter.ae.encoding.error:", err)
return nil
}
url := joinPath(peer.ConnectionString, t.AppendEntriesPath())
traceln(server.Name(), "POST", url)
httpResp, err := t.httpClient.Post(url, "application/protobuf", &b)
if httpResp == nil || err != nil {
traceln("transporter.ae.response.error:", err)
return nil
}
defer httpResp.Body.Close()
resp := &AppendEntriesResponse{}
if _, err = resp.Decode(httpResp.Body); err != nil && err != io.EOF {
traceln("transporter.ae.decoding.error:", err)
return nil
}
return resp
}
// Sends a RequestVote RPC to a peer.
func (t *HTTPTransporter) SendVoteRequest(server Server, peer *Peer, req *RequestVoteRequest) *RequestVoteResponse {
var b bytes.Buffer
if _, err := req.Encode(&b); err != nil {
traceln("transporter.rv.encoding.error:", err)
return nil
}
url := fmt.Sprintf("%s%s", peer.ConnectionString, t.RequestVotePath())
traceln(server.Name(), "POST", url)
httpResp, err := t.httpClient.Post(url, "application/protobuf", &b)
if httpResp == nil || err != nil {
traceln("transporter.rv.response.error:", err)
return nil
}
defer httpResp.Body.Close()
resp := &RequestVoteResponse{}
if _, err = resp.Decode(httpResp.Body); err != nil && err != io.EOF {
traceln("transporter.rv.decoding.error:", err)
return nil
}
return resp
}
func joinPath(connectionString, thePath string) string {
u, err := url.Parse(connectionString)
if err != nil {
panic(err)
}
u.Path = path.Join(u.Path, thePath)
return u.String()
}
// Sends a SnapshotRequest RPC to a peer.
func (t *HTTPTransporter) SendSnapshotRequest(server Server, peer *Peer, req *SnapshotRequest) *SnapshotResponse {
var b bytes.Buffer
if _, err := req.Encode(&b); err != nil {
traceln("transporter.rv.encoding.error:", err)
return nil
}
url := joinPath(peer.ConnectionString, t.snapshotPath)
traceln(server.Name(), "POST", url)
httpResp, err := t.httpClient.Post(url, "application/protobuf", &b)
if httpResp == nil || err != nil {
traceln("transporter.rv.response.error:", err)
return nil
}
defer httpResp.Body.Close()
resp := &SnapshotResponse{}
if _, err = resp.Decode(httpResp.Body); err != nil && err != io.EOF {
traceln("transporter.rv.decoding.error:", err)
return nil
}
return resp
}
// Sends a SnapshotRequest RPC to a peer.
func (t *HTTPTransporter) SendSnapshotRecoveryRequest(server Server, peer *Peer, req *SnapshotRecoveryRequest) *SnapshotRecoveryResponse {
var b bytes.Buffer
if _, err := req.Encode(&b); err != nil {
traceln("transporter.rv.encoding.error:", err)
return nil
}
url := joinPath(peer.ConnectionString, t.snapshotRecoveryPath)
traceln(server.Name(), "POST", url)
httpResp, err := t.httpClient.Post(url, "application/protobuf", &b)
if httpResp == nil || err != nil {
traceln("transporter.rv.response.error:", err)
return nil
}
defer httpResp.Body.Close()
resp := &SnapshotRecoveryResponse{}
if _, err = resp.Decode(httpResp.Body); err != nil && err != io.EOF {
traceln("transporter.rv.decoding.error:", err)
return nil
}
return resp
}
//--------------------------------------
// Incoming
//--------------------------------------
// Handles incoming AppendEntries requests.
func (t *HTTPTransporter) appendEntriesHandler(server Server) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
traceln(server.Name(), "RECV /appendEntries")
req := &AppendEntriesRequest{}
if _, err := req.Decode(r.Body); err != nil {
http.Error(w, "", http.StatusBadRequest)
return
}
resp := server.AppendEntries(req)
if resp == nil {
http.Error(w, "Failed creating response.", http.StatusInternalServerError)
return
}
if _, err := resp.Encode(w); err != nil {
http.Error(w, "", http.StatusInternalServerError)
return
}
}
}
// Handles incoming RequestVote requests.
func (t *HTTPTransporter) requestVoteHandler(server Server) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
traceln(server.Name(), "RECV /requestVote")
req := &RequestVoteRequest{}
if _, err := req.Decode(r.Body); err != nil {
http.Error(w, "", http.StatusBadRequest)
return
}
resp := server.RequestVote(req)
if resp == nil {
http.Error(w, "Failed creating response.", http.StatusInternalServerError)
return
}
if _, err := resp.Encode(w); err != nil {
http.Error(w, "", http.StatusInternalServerError)
return
}
}
}
// Handles incoming Snapshot requests.
func (t *HTTPTransporter) snapshotHandler(server Server) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
traceln(server.Name(), "RECV /snapshot")
req := &SnapshotRequest{}
if _, err := req.Decode(r.Body); err != nil {
http.Error(w, "", http.StatusBadRequest)
return
}
resp := server.RequestSnapshot(req)
if resp == nil {
http.Error(w, "Failed creating response.", http.StatusInternalServerError)
return
}
if _, err := resp.Encode(w); err != nil {
http.Error(w, "", http.StatusInternalServerError)
return
}
}
}
// Handles incoming SnapshotRecovery requests.
func (t *HTTPTransporter) snapshotRecoveryHandler(server Server) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
traceln(server.Name(), "RECV /snapshotRecovery")
req := &SnapshotRecoveryRequest{}
if _, err := req.Decode(r.Body); err != nil {
http.Error(w, "", http.StatusBadRequest)
return
}
resp := server.SnapshotRecoveryRequest(req)
if resp == nil {
http.Error(w, "Failed creating response.", http.StatusInternalServerError)
return
}
if _, err := resp.Encode(w); err != nil {
http.Error(w, "", http.StatusInternalServerError)
return
}
}
}

View File

@ -1,153 +0,0 @@
package raft
import (
"fmt"
"net"
"net/http"
"sync"
"testing"
"time"
)
// Ensure that we can start several servers and have them communicate.
func TestHTTPTransporter(t *testing.T) {
transporter := NewHTTPTransporter("/raft", testElectionTimeout)
transporter.DisableKeepAlives = true
servers := []Server{}
f0 := func(server Server, httpServer *http.Server) {
// Stop the leader and wait for an election.
server.Stop()
time.Sleep(testElectionTimeout * 2)
if servers[1].State() != Leader && servers[2].State() != Leader {
t.Fatal("Expected re-election:", servers[1].State(), servers[2].State())
}
server.Start()
}
f1 := func(server Server, httpServer *http.Server) {
}
f2 := func(server Server, httpServer *http.Server) {
}
runTestHttpServers(t, &servers, transporter, f0, f1, f2)
}
// Starts multiple independent Raft servers wrapped with HTTP servers.
func runTestHttpServers(t *testing.T, servers *[]Server, transporter *HTTPTransporter, callbacks ...func(Server, *http.Server)) {
var wg sync.WaitGroup
httpServers := []*http.Server{}
listeners := []net.Listener{}
for i := range callbacks {
wg.Add(1)
port := 9000 + i
// Create raft server.
server := newTestServer(fmt.Sprintf("localhost:%d", port), transporter)
server.SetHeartbeatInterval(testHeartbeatInterval)
server.SetElectionTimeout(testElectionTimeout)
server.Start()
defer server.Stop()
*servers = append(*servers, server)
// Create listener for HTTP server and start it.
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
panic(err)
}
defer listener.Close()
listeners = append(listeners, listener)
// Create wrapping HTTP server.
mux := http.NewServeMux()
transporter.Install(server, mux)
httpServer := &http.Server{Addr: fmt.Sprintf(":%d", port), Handler: mux}
httpServers = append(httpServers, httpServer)
go func() { httpServer.Serve(listener) }()
}
// Setup configuration.
for _, server := range *servers {
if _, err := (*servers)[0].Do(&DefaultJoinCommand{Name: server.Name(), ConnectionString: fmt.Sprintf("http://%s", server.Name())}); err != nil {
t.Fatalf("Server %s unable to join: %v", server.Name(), err)
}
}
// Wait for configuration to propagate.
time.Sleep(testHeartbeatInterval * 2)
// Execute all the callbacks at the same time.
for _i, _f := range callbacks {
i, f := _i, _f
go func() {
defer wg.Done()
f((*servers)[i], httpServers[i])
}()
}
// Wait until everything is done.
wg.Wait()
}
func BenchmarkSpeed(b *testing.B) {
transporter := NewHTTPTransporter("/raft", testElectionTimeout)
transporter.DisableKeepAlives = true
servers := []Server{}
for i := 0; i < 3; i++ {
port := 9000 + i
// Create raft server.
server := newTestServer(fmt.Sprintf("localhost:%d", port), transporter)
server.SetHeartbeatInterval(testHeartbeatInterval)
server.SetElectionTimeout(testElectionTimeout)
server.Start()
defer server.Stop()
servers = append(servers, server)
// Create listener for HTTP server and start it.
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
if err != nil {
panic(err)
}
defer listener.Close()
// Create wrapping HTTP server.
mux := http.NewServeMux()
transporter.Install(server, mux)
httpServer := &http.Server{Addr: fmt.Sprintf(":%d", port), Handler: mux}
go func() { httpServer.Serve(listener) }()
}
// Setup configuration.
for _, server := range servers {
(servers)[0].Do(&DefaultJoinCommand{Name: server.Name(), ConnectionString: fmt.Sprintf("http://%s", server.Name())})
}
c := make(chan bool)
// Wait for configuration to propagate.
time.Sleep(testHeartbeatInterval * 2)
b.ResetTimer()
for n := 0; n < b.N; n++ {
for i := 0; i < 1000; i++ {
go send(c, servers[0])
}
for i := 0; i < 1000; i++ {
<-c
}
}
}
func send(c chan bool, s Server) {
for i := 0; i < 20; i++ {
s.Do(&NOPCommand{})
}
c <- true
}

View File

@ -1,632 +0,0 @@
package raft
import (
"bufio"
"errors"
"fmt"
"io"
"os"
"sync"
"github.com/influxdb/influxdb/_vendor/raft/protobuf"
)
//------------------------------------------------------------------------------
//
// Typedefs
//
//------------------------------------------------------------------------------
// A log is a collection of log entries that are persisted to durable storage.
type Log struct {
ApplyFunc func(*LogEntry, Command) (interface{}, error)
file *os.File
path string
entries []*LogEntry
commitIndex uint64
mutex sync.RWMutex
startIndex uint64 // the index before the first entry in the Log entries
startTerm uint64
initialized bool
}
// The results of the applying a log entry.
type logResult struct {
returnValue interface{}
err error
}
//------------------------------------------------------------------------------
//
// Constructor
//
//------------------------------------------------------------------------------
// Creates a new log.
func newLog() *Log {
return &Log{
entries: make([]*LogEntry, 0),
}
}
//------------------------------------------------------------------------------
//
// Accessors
//
//------------------------------------------------------------------------------
//--------------------------------------
// Log Indices
//--------------------------------------
// The last committed index in the log.
func (l *Log) CommitIndex() uint64 {
l.mutex.RLock()
defer l.mutex.RUnlock()
return l.commitIndex
}
// The current index in the log.
func (l *Log) currentIndex() uint64 {
l.mutex.RLock()
defer l.mutex.RUnlock()
return l.internalCurrentIndex()
}
// The current index in the log without locking
func (l *Log) internalCurrentIndex() uint64 {
if len(l.entries) == 0 {
return l.startIndex
}
return l.entries[len(l.entries)-1].Index()
}
// The next index in the log.
func (l *Log) nextIndex() uint64 {
return l.currentIndex() + 1
}
// Determines if the log contains zero entries.
func (l *Log) isEmpty() bool {
l.mutex.RLock()
defer l.mutex.RUnlock()
return (len(l.entries) == 0) && (l.startIndex == 0)
}
// The name of the last command in the log.
func (l *Log) lastCommandName() string {
l.mutex.RLock()
defer l.mutex.RUnlock()
if len(l.entries) > 0 {
if entry := l.entries[len(l.entries)-1]; entry != nil {
return entry.CommandName()
}
}
return ""
}
//--------------------------------------
// Log Terms
//--------------------------------------
// The current term in the log.
func (l *Log) currentTerm() uint64 {
l.mutex.RLock()
defer l.mutex.RUnlock()
if len(l.entries) == 0 {
return l.startTerm
}
return l.entries[len(l.entries)-1].Term()
}
//------------------------------------------------------------------------------
//
// Methods
//
//------------------------------------------------------------------------------
//--------------------------------------
// State
//--------------------------------------
// Opens the log file and reads existing entries. The log can remain open and
// continue to append entries to the end of the log.
func (l *Log) open(path string) error {
// Read all the entries from the log if one exists.
var readBytes int64
var err error
debugln("log.open.open ", path)
// open log file
l.file, err = os.OpenFile(path, os.O_RDWR, 0600)
l.path = path
if err != nil {
// if the log file does not exist before
// we create the log file and set commitIndex to 0
if os.IsNotExist(err) {
l.file, err = os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0600)
debugln("log.open.create ", path)
if err == nil {
l.initialized = true
}
return err
}
return err
}
debugln("log.open.exist ", path)
// Read the file and decode entries.
for {
// Instantiate log entry and decode into it.
entry, _ := newLogEntry(l, nil, 0, 0, nil)
entry.Position, _ = l.file.Seek(0, os.SEEK_CUR)
n, err := entry.Decode(l.file)
if err != nil {
if err == io.EOF {
debugln("open.log.append: finish ")
} else {
if err = os.Truncate(path, readBytes); err != nil {
return fmt.Errorf("raft.Log: Unable to recover: %v", err)
}
}
break
}
if entry.Index() > l.startIndex {
// Append entry.
l.entries = append(l.entries, entry)
if entry.Index() <= l.commitIndex {
command, err := newCommand(entry.CommandName(), entry.Command())
if err != nil {
continue
}
l.ApplyFunc(entry, command)
}
debugln("open.log.append log index ", entry.Index())
}
readBytes += int64(n)
}
debugln("open.log.recovery number of log ", len(l.entries))
l.initialized = true
return nil
}
// Closes the log file.
func (l *Log) close() {
l.mutex.Lock()
defer l.mutex.Unlock()
if l.file != nil {
l.file.Close()
l.file = nil
}
l.entries = make([]*LogEntry, 0)
}
// sync to disk
func (l *Log) sync() error {
return l.file.Sync()
}
//--------------------------------------
// Entries
//--------------------------------------
// Creates a log entry associated with this log.
func (l *Log) createEntry(term uint64, command Command, e *ev) (*LogEntry, error) {
return newLogEntry(l, e, l.nextIndex(), term, command)
}
// Retrieves an entry from the log. If the entry has been eliminated because
// of a snapshot then nil is returned.
func (l *Log) getEntry(index uint64) *LogEntry {
l.mutex.RLock()
defer l.mutex.RUnlock()
if index <= l.startIndex || index > (l.startIndex+uint64(len(l.entries))) {
return nil
}
return l.entries[index-l.startIndex-1]
}
// Checks if the log contains a given index/term combination.
func (l *Log) containsEntry(index uint64, term uint64) bool {
entry := l.getEntry(index)
return (entry != nil && entry.Term() == term)
}
// Retrieves a list of entries after a given index as well as the term of the
// index provided. A nil list of entries is returned if the index no longer
// exists because a snapshot was made.
func (l *Log) getEntriesAfter(index uint64, maxLogEntriesPerRequest uint64) ([]*LogEntry, uint64) {
l.mutex.RLock()
defer l.mutex.RUnlock()
// Return nil if index is before the start of the log.
if index < l.startIndex {
traceln("log.entriesAfter.before: ", index, " ", l.startIndex)
return nil, 0
}
// Return an error if the index doesn't exist.
if index > (uint64(len(l.entries)) + l.startIndex) {
panic(fmt.Sprintf("raft: Index is beyond end of log: %v %v", len(l.entries), index))
}
// If we're going from the beginning of the log then return the whole log.
if index == l.startIndex {
traceln("log.entriesAfter.beginning: ", index, " ", l.startIndex)
return l.entries, l.startTerm
}
traceln("log.entriesAfter.partial: ", index, " ", l.entries[len(l.entries)-1].Index)
entries := l.entries[index-l.startIndex:]
length := len(entries)
traceln("log.entriesAfter: startIndex:", l.startIndex, " length", len(l.entries))
if uint64(length) < maxLogEntriesPerRequest {
// Determine the term at the given entry and return a subslice.
return entries, l.entries[index-1-l.startIndex].Term()
} else {
return entries[:maxLogEntriesPerRequest], l.entries[index-1-l.startIndex].Term()
}
}
//--------------------------------------
// Commit
//--------------------------------------
// Retrieves the last index and term that has been committed to the log.
func (l *Log) commitInfo() (index uint64, term uint64) {
l.mutex.RLock()
defer l.mutex.RUnlock()
// If we don't have any committed entries then just return zeros.
if l.commitIndex == 0 {
return 0, 0
}
// No new commit log after snapshot
if l.commitIndex == l.startIndex {
return l.startIndex, l.startTerm
}
// Return the last index & term from the last committed entry.
debugln("commitInfo.get.[", l.commitIndex, "/", l.startIndex, "]")
entry := l.entries[l.commitIndex-1-l.startIndex]
return entry.Index(), entry.Term()
}
// Retrieves the last index and term that has been appended to the log.
func (l *Log) lastInfo() (index uint64, term uint64) {
l.mutex.RLock()
defer l.mutex.RUnlock()
// If we don't have any entries then just return zeros.
if len(l.entries) == 0 {
return l.startIndex, l.startTerm
}
// Return the last index & term
entry := l.entries[len(l.entries)-1]
return entry.Index(), entry.Term()
}
// Updates the commit index
func (l *Log) updateCommitIndex(index uint64) {
l.mutex.Lock()
defer l.mutex.Unlock()
if index > l.commitIndex {
l.commitIndex = index
}
debugln("update.commit.index ", index)
}
// Updates the commit index and writes entries after that index to the stable storage.
func (l *Log) setCommitIndex(index uint64) error {
l.mutex.Lock()
defer l.mutex.Unlock()
// this is not error any more after limited the number of sending entries
// commit up to what we already have
if index > l.startIndex+uint64(len(l.entries)) {
debugln("raft.Log: Commit index", index, "set back to ", len(l.entries))
index = l.startIndex + uint64(len(l.entries))
}
// Do not allow previous indices to be committed again.
// This could happens, since the guarantee is that the new leader has up-to-dated
// log entries rather than has most up-to-dated committed index
// For example, Leader 1 send log 80 to follower 2 and follower 3
// follower 2 and follow 3 all got the new entries and reply
// leader 1 committed entry 80 and send reply to follower 2 and follower3
// follower 2 receive the new committed index and update committed index to 80
// leader 1 fail to send the committed index to follower 3
// follower 3 promote to leader (server 1 and server 2 will vote, since leader 3
// has up-to-dated the entries)
// when new leader 3 send heartbeat with committed index = 0 to follower 2,
// follower 2 should reply success and let leader 3 update the committed index to 80
if index < l.commitIndex {
return nil
}
// Find all entries whose index is between the previous index and the current index.
for i := l.commitIndex + 1; i <= index; i++ {
entryIndex := i - 1 - l.startIndex
entry := l.entries[entryIndex]
// Update commit index.
l.commitIndex = entry.Index()
// Decode the command.
command, err := newCommand(entry.CommandName(), entry.Command())
if err != nil {
return err
}
// Apply the changes to the state machine and store the error code.
returnValue, err := l.ApplyFunc(entry, command)
debugf("setCommitIndex.set.result index: %v, entries index: %v", i, entryIndex)
if entry.event != nil {
entry.event.returnValue = returnValue
entry.event.c <- err
}
_, isJoinCommand := command.(JoinCommand)
// we can only commit up to the most recent join command
// if there is a join in this batch of commands.
// after this commit, we need to recalculate the majority.
if isJoinCommand {
return nil
}
}
return nil
}
// Set the commitIndex at the head of the log file to the current
// commit Index. This should be called after obtained a log lock
func (l *Log) flushCommitIndex() {
l.file.Seek(0, os.SEEK_SET)
fmt.Fprintf(l.file, "%8x\n", l.commitIndex)
l.file.Seek(0, os.SEEK_END)
}
//--------------------------------------
// Truncation
//--------------------------------------
// Truncates the log to the given index and term. This only works if the log
// at the index has not been committed.
func (l *Log) truncate(index uint64, term uint64) error {
l.mutex.Lock()
defer l.mutex.Unlock()
debugln("log.truncate: ", index)
// Do not allow committed entries to be truncated.
if index < l.commitIndex {
debugln("log.truncate.before")
return fmt.Errorf("raft.Log: Index is already committed (%v): (IDX=%v, TERM=%v)", l.commitIndex, index, term)
}
// Do not truncate past end of entries.
if index > l.startIndex+uint64(len(l.entries)) {
debugln("log.truncate.after")
return fmt.Errorf("raft.Log: Entry index does not exist (MAX=%v): (IDX=%v, TERM=%v)", len(l.entries), index, term)
}
// If we're truncating everything then just clear the entries.
if index == l.startIndex {
debugln("log.truncate.clear")
l.file.Truncate(0)
l.file.Seek(0, os.SEEK_SET)
// notify clients if this node is the previous leader
for _, entry := range l.entries {
if entry.event != nil {
entry.event.c <- errors.New("command failed to be committed due to node failure")
}
}
l.entries = []*LogEntry{}
} else {
// Do not truncate if the entry at index does not have the matching term.
entry := l.entries[index-l.startIndex-1]
if len(l.entries) > 0 && entry.Term() != term {
debugln("log.truncate.termMismatch")
return fmt.Errorf("raft.Log: Entry at index does not have matching term (%v): (IDX=%v, TERM=%v)", entry.Term(), index, term)
}
// Otherwise truncate up to the desired entry.
if index < l.startIndex+uint64(len(l.entries)) {
debugln("log.truncate.finish")
position := l.entries[index-l.startIndex].Position
l.file.Truncate(position)
l.file.Seek(position, os.SEEK_SET)
// notify clients if this node is the previous leader
for i := index - l.startIndex; i < uint64(len(l.entries)); i++ {
entry := l.entries[i]
if entry.event != nil {
entry.event.c <- errors.New("command failed to be committed due to node failure")
}
}
l.entries = l.entries[0 : index-l.startIndex]
}
}
return nil
}
//--------------------------------------
// Append
//--------------------------------------
// Appends a series of entries to the log.
func (l *Log) appendEntries(entries []*protobuf.LogEntry) error {
l.mutex.Lock()
defer l.mutex.Unlock()
startPosition, _ := l.file.Seek(0, os.SEEK_CUR)
w := bufio.NewWriter(l.file)
var size int64
var err error
// Append each entry but exit if we hit an error.
for i := range entries {
logEntry := &LogEntry{
log: l,
Position: startPosition,
pb: entries[i],
}
if size, err = l.writeEntry(logEntry, w); err != nil {
return err
}
startPosition += size
}
w.Flush()
err = l.sync()
if err != nil {
panic(err)
}
return nil
}
// Writes a single log entry to the end of the log.
func (l *Log) appendEntry(entry *LogEntry) error {
l.mutex.Lock()
defer l.mutex.Unlock()
if l.file == nil {
return errors.New("raft.Log: Log is not open")
}
// Make sure the term and index are greater than the previous.
if len(l.entries) > 0 {
lastEntry := l.entries[len(l.entries)-1]
if entry.Term() < lastEntry.Term() {
return fmt.Errorf("raft.Log: Cannot append entry with earlier term (%x:%x <= %x:%x)", entry.Term(), entry.Index(), lastEntry.Term(), lastEntry.Index())
} else if entry.Term() == lastEntry.Term() && entry.Index() <= lastEntry.Index() {
return fmt.Errorf("raft.Log: Cannot append entry with earlier index in the same term (%x:%x <= %x:%x)", entry.Term(), entry.Index(), lastEntry.Term(), lastEntry.Index())
}
}
position, _ := l.file.Seek(0, os.SEEK_CUR)
entry.Position = position
// Write to storage.
if _, err := entry.Encode(l.file); err != nil {
return err
}
// Append to entries list if stored on disk.
l.entries = append(l.entries, entry)
return nil
}
// appendEntry with Buffered io
func (l *Log) writeEntry(entry *LogEntry, w io.Writer) (int64, error) {
if l.file == nil {
return -1, errors.New("raft.Log: Log is not open")
}
// Make sure the term and index are greater than the previous.
if len(l.entries) > 0 {
lastEntry := l.entries[len(l.entries)-1]
if entry.Term() < lastEntry.Term() {
return -1, fmt.Errorf("raft.Log: Cannot append entry with earlier term (%x:%x <= %x:%x)", entry.Term(), entry.Index(), lastEntry.Term(), lastEntry.Index())
} else if entry.Term() == lastEntry.Term() && entry.Index() <= lastEntry.Index() {
return -1, fmt.Errorf("raft.Log: Cannot append entry with earlier index in the same term (%x:%x <= %x:%x)", entry.Term(), entry.Index(), lastEntry.Term(), lastEntry.Index())
}
}
// Write to storage.
size, err := entry.Encode(w)
if err != nil {
return -1, err
}
// Append to entries list if stored on disk.
l.entries = append(l.entries, entry)
return int64(size), nil
}
//--------------------------------------
// Log compaction
//--------------------------------------
// compact the log before index (including index)
func (l *Log) compact(index uint64, term uint64) error {
var entries []*LogEntry
l.mutex.Lock()
defer l.mutex.Unlock()
if index == 0 {
return nil
}
// nothing to compaction
// the index may be greater than the current index if
// we just recovery from on snapshot
if index >= l.internalCurrentIndex() {
entries = make([]*LogEntry, 0)
} else {
// get all log entries after index
entries = l.entries[index-l.startIndex:]
}
// create a new log file and add all the entries
new_file_path := l.path + ".new"
file, err := os.OpenFile(new_file_path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
return err
}
for _, entry := range entries {
position, _ := l.file.Seek(0, os.SEEK_CUR)
entry.Position = position
if _, err = entry.Encode(file); err != nil {
file.Close()
os.Remove(new_file_path)
return err
}
}
file.Sync()
old_file := l.file
// rename the new log file
err = os.Rename(new_file_path, l.path)
if err != nil {
file.Close()
os.Remove(new_file_path)
return err
}
l.file = file
// close the old log file
old_file.Close()
// compaction the in memory log
l.entries = entries
l.startIndex = index
l.startTerm = term
return nil
}

View File

@ -1,107 +0,0 @@
package raft
import (
"bytes"
"encoding/json"
"fmt"
"io"
"code.google.com/p/gogoprotobuf/proto"
"github.com/influxdb/influxdb/_vendor/raft/protobuf"
)
// A log entry stores a single item in the log.
type LogEntry struct {
pb *protobuf.LogEntry
Position int64 // position in the log file
log *Log
event *ev
}
// Creates a new log entry associated with a log.
func newLogEntry(log *Log, event *ev, index uint64, term uint64, command Command) (*LogEntry, error) {
var buf bytes.Buffer
var commandName string
if command != nil {
commandName = command.CommandName()
if encoder, ok := command.(CommandEncoder); ok {
if err := encoder.Encode(&buf); err != nil {
return nil, err
}
} else {
if err := json.NewEncoder(&buf).Encode(command); err != nil {
return nil, err
}
}
}
pb := &protobuf.LogEntry{
Index: proto.Uint64(index),
Term: proto.Uint64(term),
CommandName: proto.String(commandName),
Command: buf.Bytes(),
}
e := &LogEntry{
pb: pb,
log: log,
event: event,
}
return e, nil
}
func (e *LogEntry) Index() uint64 {
return e.pb.GetIndex()
}
func (e *LogEntry) Term() uint64 {
return e.pb.GetTerm()
}
func (e *LogEntry) CommandName() string {
return e.pb.GetCommandName()
}
func (e *LogEntry) Command() []byte {
return e.pb.GetCommand()
}
// Encodes the log entry to a buffer. Returns the number of bytes
// written and any error that may have occurred.
func (e *LogEntry) Encode(w io.Writer) (int, error) {
b, err := proto.Marshal(e.pb)
if err != nil {
return -1, err
}
if _, err = fmt.Fprintf(w, "%8x\n", len(b)); err != nil {
return -1, err
}
return w.Write(b)
}
// Decodes the log entry from a buffer. Returns the number of bytes read and
// any error that occurs.
func (e *LogEntry) Decode(r io.Reader) (int, error) {
var length int
_, err := fmt.Fscanf(r, "%8x\n", &length)
if err != nil {
return -1, err
}
data := make([]byte, length)
_, err = io.ReadFull(r, data)
if err != nil {
return -1, err
}
if err = proto.Unmarshal(data, e.pb); err != nil {
return -1, err
}
return length + 8 + 1, nil
}

View File

@ -1,232 +0,0 @@
package raft
import (
"io/ioutil"
"os"
"reflect"
"testing"
)
//------------------------------------------------------------------------------
//
// Tests
//
//------------------------------------------------------------------------------
//--------------------------------------
// Append
//--------------------------------------
// Ensure that we can append to a new log.
func TestLogNewLog(t *testing.T) {
path := getLogPath()
log := newLog()
log.ApplyFunc = func(e *LogEntry, c Command) (interface{}, error) {
return nil, nil
}
if err := log.open(path); err != nil {
t.Fatalf("Unable to open log: %v", err)
}
defer log.close()
defer os.Remove(path)
e, _ := newLogEntry(log, nil, 1, 1, &testCommand1{Val: "foo", I: 20})
if err := log.appendEntry(e); err != nil {
t.Fatalf("Unable to append: %v", err)
}
e, _ = newLogEntry(log, nil, 2, 1, &testCommand2{X: 100})
if err := log.appendEntry(e); err != nil {
t.Fatalf("Unable to append: %v", err)
}
e, _ = newLogEntry(log, nil, 3, 2, &testCommand1{Val: "bar", I: 0})
if err := log.appendEntry(e); err != nil {
t.Fatalf("Unable to append: %v", err)
}
// Partial commit.
if err := log.setCommitIndex(2); err != nil {
t.Fatalf("Unable to partially commit: %v", err)
}
if index, term := log.commitInfo(); index != 2 || term != 1 {
t.Fatalf("Invalid commit info [IDX=%v, TERM=%v]", index, term)
}
// Full commit.
if err := log.setCommitIndex(3); err != nil {
t.Fatalf("Unable to commit: %v", err)
}
if index, term := log.commitInfo(); index != 3 || term != 2 {
t.Fatalf("Invalid commit info [IDX=%v, TERM=%v]", index, term)
}
}
// Ensure that we can decode and encode to an existing log.
func TestLogExistingLog(t *testing.T) {
tmpLog := newLog()
e0, _ := newLogEntry(tmpLog, nil, 1, 1, &testCommand1{Val: "foo", I: 20})
e1, _ := newLogEntry(tmpLog, nil, 2, 1, &testCommand2{X: 100})
e2, _ := newLogEntry(tmpLog, nil, 3, 2, &testCommand1{Val: "bar", I: 0})
log, path := setupLog([]*LogEntry{e0, e1, e2})
defer log.close()
defer os.Remove(path)
// Validate existing log entries.
if len(log.entries) != 3 {
t.Fatalf("Expected 3 entries, got %d", len(log.entries))
}
if log.entries[0].Index() != 1 || log.entries[0].Term() != 1 {
t.Fatalf("Unexpected entry[0]: %v", log.entries[0])
}
if log.entries[1].Index() != 2 || log.entries[1].Term() != 1 {
t.Fatalf("Unexpected entry[1]: %v", log.entries[1])
}
if log.entries[2].Index() != 3 || log.entries[2].Term() != 2 {
t.Fatalf("Unexpected entry[2]: %v", log.entries[2])
}
}
// Ensure that we can check the contents of the log by index/term.
func TestLogContainsEntries(t *testing.T) {
tmpLog := newLog()
e0, _ := newLogEntry(tmpLog, nil, 1, 1, &testCommand1{Val: "foo", I: 20})
e1, _ := newLogEntry(tmpLog, nil, 2, 1, &testCommand2{X: 100})
e2, _ := newLogEntry(tmpLog, nil, 3, 2, &testCommand1{Val: "bar", I: 0})
log, path := setupLog([]*LogEntry{e0, e1, e2})
defer log.close()
defer os.Remove(path)
if log.containsEntry(0, 0) {
t.Fatalf("Zero-index entry should not exist in log.")
}
if log.containsEntry(1, 0) {
t.Fatalf("Entry with mismatched term should not exist")
}
if log.containsEntry(4, 0) {
t.Fatalf("Out-of-range entry should not exist")
}
if !log.containsEntry(2, 1) {
t.Fatalf("Entry 2/1 should exist")
}
if !log.containsEntry(3, 2) {
t.Fatalf("Entry 2/1 should exist")
}
}
// Ensure that we can recover from an incomplete/corrupt log and continue logging.
func TestLogRecovery(t *testing.T) {
tmpLog := newLog()
e0, _ := newLogEntry(tmpLog, nil, 1, 1, &testCommand1{Val: "foo", I: 20})
e1, _ := newLogEntry(tmpLog, nil, 2, 1, &testCommand2{X: 100})
f, _ := ioutil.TempFile("", "raft-log-")
e0.Encode(f)
e1.Encode(f)
f.WriteString("CORRUPT!")
f.Close()
log := newLog()
log.ApplyFunc = func(e *LogEntry, c Command) (interface{}, error) {
return nil, nil
}
if err := log.open(f.Name()); err != nil {
t.Fatalf("Unable to open log: %v", err)
}
defer log.close()
defer os.Remove(f.Name())
e, _ := newLogEntry(log, nil, 3, 2, &testCommand1{Val: "bat", I: -5})
if err := log.appendEntry(e); err != nil {
t.Fatalf("Unable to append: %v", err)
}
// Validate existing log entries.
if len(log.entries) != 3 {
t.Fatalf("Expected 3 entries, got %d", len(log.entries))
}
if log.entries[0].Index() != 1 || log.entries[0].Term() != 1 {
t.Fatalf("Unexpected entry[0]: %v", log.entries[0])
}
if log.entries[1].Index() != 2 || log.entries[1].Term() != 1 {
t.Fatalf("Unexpected entry[1]: %v", log.entries[1])
}
if log.entries[2].Index() != 3 || log.entries[2].Term() != 2 {
t.Fatalf("Unexpected entry[2]: %v", log.entries[2])
}
}
//--------------------------------------
// Append
//--------------------------------------
// Ensure that we can truncate uncommitted entries in the log.
func TestLogTruncate(t *testing.T) {
log, path := setupLog(nil)
if err := log.open(path); err != nil {
t.Fatalf("Unable to open log: %v", err)
}
defer os.Remove(path)
entry1, _ := newLogEntry(log, nil, 1, 1, &testCommand1{Val: "foo", I: 20})
if err := log.appendEntry(entry1); err != nil {
t.Fatalf("Unable to append: %v", err)
}
entry2, _ := newLogEntry(log, nil, 2, 1, &testCommand2{X: 100})
if err := log.appendEntry(entry2); err != nil {
t.Fatalf("Unable to append: %v", err)
}
entry3, _ := newLogEntry(log, nil, 3, 2, &testCommand1{Val: "bar", I: 0})
if err := log.appendEntry(entry3); err != nil {
t.Fatalf("Unable to append: %v", err)
}
if err := log.setCommitIndex(2); err != nil {
t.Fatalf("Unable to partially commit: %v", err)
}
// Truncate committed entry.
if err := log.truncate(1, 1); err == nil || err.Error() != "raft.Log: Index is already committed (2): (IDX=1, TERM=1)" {
t.Fatalf("Truncating committed entries shouldn't work: %v", err)
}
// Truncate past end of log.
if err := log.truncate(4, 2); err == nil || err.Error() != "raft.Log: Entry index does not exist (MAX=3): (IDX=4, TERM=2)" {
t.Fatalf("Truncating past end-of-log shouldn't work: %v", err)
}
// Truncate entry with mismatched term.
if err := log.truncate(2, 2); err == nil || err.Error() != "raft.Log: Entry at index does not have matching term (1): (IDX=2, TERM=2)" {
t.Fatalf("Truncating mismatched entries shouldn't work: %v", err)
}
// Truncate end of log.
if err := log.truncate(3, 2); !(err == nil && reflect.DeepEqual(log.entries, []*LogEntry{entry1, entry2, entry3})) {
t.Fatalf("Truncating end of log should work: %v\n\nEntries:\nActual: %v\nExpected: %v", err, log.entries, []*LogEntry{entry1, entry2, entry3})
}
// Truncate at last commit.
if err := log.truncate(2, 1); !(err == nil && reflect.DeepEqual(log.entries, []*LogEntry{entry1, entry2})) {
t.Fatalf("Truncating at last commit should work: %v\n\nEntries:\nActual: %v\nExpected: %v", err, log.entries, []*LogEntry{entry1, entry2})
}
// Append after truncate
if err := log.appendEntry(entry3); err != nil {
t.Fatalf("Unable to append after truncate: %v", err)
}
log.close()
// Recovery the truncated log
log = newLog()
if err := log.open(path); err != nil {
t.Fatalf("Unable to open log: %v", err)
}
// Validate existing log entries.
if len(log.entries) != 3 {
t.Fatalf("Expected 3 entries, got %d", len(log.entries))
}
if log.entries[0].Index() != 1 || log.entries[0].Term() != 1 {
t.Fatalf("Unexpected entry[0]: %v", log.entries[0])
}
if log.entries[1].Index() != 2 || log.entries[1].Term() != 1 {
t.Fatalf("Unexpected entry[1]: %v", log.entries[1])
}
if log.entries[2].Index() != 3 || log.entries[2].Term() != 2 {
t.Fatalf("Unexpected entry[2]: %v", log.entries[2])
}
}

View File

@ -1,320 +0,0 @@
package raft
import (
"sync"
"time"
)
//------------------------------------------------------------------------------
//
// Typedefs
//
//------------------------------------------------------------------------------
// A peer is a reference to another server involved in the consensus protocol.
type Peer struct {
server *server
Name string `json:"name"`
ConnectionString string `json:"connectionString"`
prevLogIndex uint64
stopChan chan bool
heartbeatInterval time.Duration
lastActivity time.Time
sync.RWMutex
}
//------------------------------------------------------------------------------
//
// Constructor
//
//------------------------------------------------------------------------------
// Creates a new peer.
func newPeer(server *server, name string, connectionString string, heartbeatInterval time.Duration) *Peer {
return &Peer{
server: server,
Name: name,
ConnectionString: connectionString,
heartbeatInterval: heartbeatInterval,
}
}
//------------------------------------------------------------------------------
//
// Accessors
//
//------------------------------------------------------------------------------
// Sets the heartbeat timeout.
func (p *Peer) setHeartbeatInterval(duration time.Duration) {
p.heartbeatInterval = duration
}
//--------------------------------------
// Prev log index
//--------------------------------------
// Retrieves the previous log index.
func (p *Peer) getPrevLogIndex() uint64 {
p.RLock()
defer p.RUnlock()
return p.prevLogIndex
}
// Sets the previous log index.
func (p *Peer) setPrevLogIndex(value uint64) {
p.Lock()
defer p.Unlock()
p.prevLogIndex = value
}
func (p *Peer) setLastActivity(now time.Time) {
p.Lock()
defer p.Unlock()
p.lastActivity = now
}
//------------------------------------------------------------------------------
//
// Methods
//
//------------------------------------------------------------------------------
//--------------------------------------
// Heartbeat
//--------------------------------------
// Starts the peer heartbeat.
func (p *Peer) startHeartbeat() {
p.stopChan = make(chan bool)
c := make(chan bool)
p.setLastActivity(time.Now())
p.server.routineGroup.Add(1)
go func() {
defer p.server.routineGroup.Done()
p.heartbeat(c)
}()
<-c
}
// Stops the peer heartbeat.
func (p *Peer) stopHeartbeat(flush bool) {
p.setLastActivity(time.Time{})
p.stopChan <- flush
}
// LastActivity returns the last time any response was received from the peer.
func (p *Peer) LastActivity() time.Time {
p.RLock()
defer p.RUnlock()
return p.lastActivity
}
//--------------------------------------
// Copying
//--------------------------------------
// Clones the state of the peer. The clone is not attached to a server and
// the heartbeat timer will not exist.
func (p *Peer) clone() *Peer {
p.Lock()
defer p.Unlock()
return &Peer{
Name: p.Name,
ConnectionString: p.ConnectionString,
prevLogIndex: p.prevLogIndex,
lastActivity: p.lastActivity,
}
}
//--------------------------------------
// Heartbeat
//--------------------------------------
// Listens to the heartbeat timeout and flushes an AppendEntries RPC.
func (p *Peer) heartbeat(c chan bool) {
stopChan := p.stopChan
c <- true
ticker := time.Tick(p.heartbeatInterval)
debugln("peer.heartbeat: ", p.Name, p.heartbeatInterval)
for {
select {
case flush := <-stopChan:
if flush {
// before we can safely remove a node
// we must flush the remove command to the node first
p.flush()
debugln("peer.heartbeat.stop.with.flush: ", p.Name)
return
} else {
debugln("peer.heartbeat.stop: ", p.Name)
return
}
case <-ticker:
start := time.Now()
p.flush()
duration := time.Now().Sub(start)
p.server.DispatchEvent(newEvent(HeartbeatEventType, duration, nil))
}
}
}
func (p *Peer) flush() {
debugln("peer.heartbeat.flush: ", p.Name)
prevLogIndex := p.getPrevLogIndex()
term := p.server.currentTerm
entries, prevLogTerm := p.server.log.getEntriesAfter(prevLogIndex, p.server.maxLogEntriesPerRequest)
if entries != nil {
p.sendAppendEntriesRequest(newAppendEntriesRequest(term, prevLogIndex, prevLogTerm, p.server.log.CommitIndex(), p.server.name, entries))
} else {
p.sendSnapshotRequest(newSnapshotRequest(p.server.name, p.server.snapshot))
}
}
//--------------------------------------
// Append Entries
//--------------------------------------
// Sends an AppendEntries request to the peer through the transport.
func (p *Peer) sendAppendEntriesRequest(req *AppendEntriesRequest) {
tracef("peer.append.send: %s->%s [prevLog:%v length: %v]\n",
p.server.Name(), p.Name, req.PrevLogIndex, len(req.Entries))
resp := p.server.Transporter().SendAppendEntriesRequest(p.server, p, req)
if resp == nil {
p.server.DispatchEvent(newEvent(HeartbeatIntervalEventType, p, nil))
debugln("peer.append.timeout: ", p.server.Name(), "->", p.Name)
return
}
traceln("peer.append.resp: ", p.server.Name(), "<-", p.Name)
p.setLastActivity(time.Now())
// If successful then update the previous log index.
p.Lock()
if resp.Success() {
if len(req.Entries) > 0 {
p.prevLogIndex = req.Entries[len(req.Entries)-1].GetIndex()
// if peer append a log entry from the current term
// we set append to true
if req.Entries[len(req.Entries)-1].GetTerm() == p.server.currentTerm {
resp.append = true
}
}
traceln("peer.append.resp.success: ", p.Name, "; idx =", p.prevLogIndex)
// If it was unsuccessful then decrement the previous log index and
// we'll try again next time.
} else {
if resp.Term() > p.server.Term() {
// this happens when there is a new leader comes up that this *leader* has not
// known yet.
// this server can know until the new leader send a ae with higher term
// or this server finish processing this response.
debugln("peer.append.resp.not.update: new.leader.found")
} else if resp.Term() == req.Term && resp.CommitIndex() >= p.prevLogIndex {
// we may miss a response from peer
// so maybe the peer has committed the logs we just sent
// but we did not receive the successful reply and did not increase
// the prevLogIndex
// peer failed to truncate the log and sent a fail reply at this time
// we just need to update peer's prevLog index to commitIndex
p.prevLogIndex = resp.CommitIndex()
debugln("peer.append.resp.update: ", p.Name, "; idx =", p.prevLogIndex)
} else if p.prevLogIndex > 0 {
// Decrement the previous log index down until we find a match. Don't
// let it go below where the peer's commit index is though. That's a
// problem.
p.prevLogIndex--
// if it not enough, we directly decrease to the index of the
if p.prevLogIndex > resp.Index() {
p.prevLogIndex = resp.Index()
}
debugln("peer.append.resp.decrement: ", p.Name, "; idx =", p.prevLogIndex)
}
}
p.Unlock()
// Attach the peer to resp, thus server can know where it comes from
resp.peer = p.Name
// Send response to server for processing.
p.server.sendAsync(resp)
}
// Sends an Snapshot request to the peer through the transport.
func (p *Peer) sendSnapshotRequest(req *SnapshotRequest) {
debugln("peer.snap.send: ", p.Name)
resp := p.server.Transporter().SendSnapshotRequest(p.server, p, req)
if resp == nil {
debugln("peer.snap.timeout: ", p.Name)
return
}
debugln("peer.snap.recv: ", p.Name)
// If successful, the peer should have been to snapshot state
// Send it the snapshot!
p.setLastActivity(time.Now())
if resp.Success {
p.sendSnapshotRecoveryRequest()
} else {
debugln("peer.snap.failed: ", p.Name)
return
}
}
// Sends an Snapshot Recovery request to the peer through the transport.
func (p *Peer) sendSnapshotRecoveryRequest() {
req := newSnapshotRecoveryRequest(p.server.name, p.server.snapshot)
debugln("peer.snap.recovery.send: ", p.Name)
resp := p.server.Transporter().SendSnapshotRecoveryRequest(p.server, p, req)
if resp == nil {
debugln("peer.snap.recovery.timeout: ", p.Name)
return
}
p.setLastActivity(time.Now())
if resp.Success {
p.prevLogIndex = req.LastIndex
} else {
debugln("peer.snap.recovery.failed: ", p.Name)
return
}
p.server.sendAsync(resp)
}
//--------------------------------------
// Vote Requests
//--------------------------------------
// send VoteRequest Request
func (p *Peer) sendVoteRequest(req *RequestVoteRequest, c chan *RequestVoteResponse) {
debugln("peer.vote: ", p.server.Name(), "->", p.Name)
req.peer = p
if resp := p.server.Transporter().SendVoteRequest(p.server, p, req); resp != nil {
debugln("peer.vote.recv: ", p.server.Name(), "<-", p.Name)
p.setLastActivity(time.Now())
resp.peer = p
c <- resp
} else {
debugln("peer.vote.failed: ", p.server.Name(), "<-", p.Name)
}
}

View File

@ -1,699 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: append_entries_request.proto
// DO NOT EDIT!
/*
Package protobuf is a generated protocol buffer package.
It is generated from these files:
append_entries_request.proto
append_entries_responses.proto
log_entry.proto
request_vote_request.proto
request_vote_responses.proto
snapshot_recovery_request.proto
snapshot_recovery_response.proto
snapshot_request.proto
snapshot_response.proto
It has these top-level messages:
AppendEntriesRequest
*/
package protobuf
import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"
// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
import io1 "io"
import fmt4 "fmt"
import code_google_com_p_gogoprotobuf_proto2 "code.google.com/p/gogoprotobuf/proto"
import fmt5 "fmt"
import strings2 "strings"
import reflect2 "reflect"
import fmt6 "fmt"
import strings3 "strings"
import code_google_com_p_gogoprotobuf_proto3 "code.google.com/p/gogoprotobuf/proto"
import sort1 "sort"
import strconv1 "strconv"
import reflect3 "reflect"
import fmt7 "fmt"
import bytes1 "bytes"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type AppendEntriesRequest struct {
Term *uint64 `protobuf:"varint,1,req" json:"Term,omitempty"`
PrevLogIndex *uint64 `protobuf:"varint,2,req" json:"PrevLogIndex,omitempty"`
PrevLogTerm *uint64 `protobuf:"varint,3,req" json:"PrevLogTerm,omitempty"`
CommitIndex *uint64 `protobuf:"varint,4,req" json:"CommitIndex,omitempty"`
LeaderName *string `protobuf:"bytes,5,req" json:"LeaderName,omitempty"`
Entries []*LogEntry `protobuf:"bytes,6,rep" json:"Entries,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *AppendEntriesRequest) Reset() { *m = AppendEntriesRequest{} }
func (*AppendEntriesRequest) ProtoMessage() {}
func (m *AppendEntriesRequest) GetTerm() uint64 {
if m != nil && m.Term != nil {
return *m.Term
}
return 0
}
func (m *AppendEntriesRequest) GetPrevLogIndex() uint64 {
if m != nil && m.PrevLogIndex != nil {
return *m.PrevLogIndex
}
return 0
}
func (m *AppendEntriesRequest) GetPrevLogTerm() uint64 {
if m != nil && m.PrevLogTerm != nil {
return *m.PrevLogTerm
}
return 0
}
func (m *AppendEntriesRequest) GetCommitIndex() uint64 {
if m != nil && m.CommitIndex != nil {
return *m.CommitIndex
}
return 0
}
func (m *AppendEntriesRequest) GetLeaderName() string {
if m != nil && m.LeaderName != nil {
return *m.LeaderName
}
return ""
}
func (m *AppendEntriesRequest) GetEntries() []*LogEntry {
if m != nil {
return m.Entries
}
return nil
}
func init() {
}
func (m *AppendEntriesRequest) Unmarshal(data []byte) error {
l := len(data)
index := 0
for index < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io1.ErrUnexpectedEOF
}
b := data[index]
index++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
switch fieldNum {
case 1:
if wireType != 0 {
return fmt4.Errorf("proto: wrong wireType = %d for field Term", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io1.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Term = &v
case 2:
if wireType != 0 {
return fmt4.Errorf("proto: wrong wireType = %d for field PrevLogIndex", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io1.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.PrevLogIndex = &v
case 3:
if wireType != 0 {
return fmt4.Errorf("proto: wrong wireType = %d for field PrevLogTerm", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io1.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.PrevLogTerm = &v
case 4:
if wireType != 0 {
return fmt4.Errorf("proto: wrong wireType = %d for field CommitIndex", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io1.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.CommitIndex = &v
case 5:
if wireType != 2 {
return fmt4.Errorf("proto: wrong wireType = %d for field LeaderName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io1.ErrUnexpectedEOF
}
b := data[index]
index++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + int(stringLen)
if postIndex > l {
return io1.ErrUnexpectedEOF
}
s := string(data[index:postIndex])
m.LeaderName = &s
index = postIndex
case 6:
if wireType != 2 {
return fmt4.Errorf("proto: wrong wireType = %d for field Entries", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if index >= l {
return io1.ErrUnexpectedEOF
}
b := data[index]
index++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + msglen
if postIndex > l {
return io1.ErrUnexpectedEOF
}
m.Entries = append(m.Entries, &LogEntry{})
m.Entries[len(m.Entries)-1].Unmarshal(data[index:postIndex])
index = postIndex
default:
var sizeOfWire int
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
index -= sizeOfWire
skippy, err := code_google_com_p_gogoprotobuf_proto2.Skip(data[index:])
if err != nil {
return err
}
if (index + skippy) > l {
return io1.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
index += skippy
}
}
return nil
}
func (this *AppendEntriesRequest) String() string {
if this == nil {
return "nil"
}
s := strings2.Join([]string{`&AppendEntriesRequest{`,
`Term:` + valueToStringAppendEntriesRequest(this.Term) + `,`,
`PrevLogIndex:` + valueToStringAppendEntriesRequest(this.PrevLogIndex) + `,`,
`PrevLogTerm:` + valueToStringAppendEntriesRequest(this.PrevLogTerm) + `,`,
`CommitIndex:` + valueToStringAppendEntriesRequest(this.CommitIndex) + `,`,
`LeaderName:` + valueToStringAppendEntriesRequest(this.LeaderName) + `,`,
`Entries:` + strings2.Replace(fmt5.Sprintf("%v", this.Entries), "LogEntry", "LogEntry", 1) + `,`,
`XXX_unrecognized:` + fmt5.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringAppendEntriesRequest(v interface{}) string {
rv := reflect2.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect2.Indirect(rv).Interface()
return fmt5.Sprintf("*%v", pv)
}
func (m *AppendEntriesRequest) Size() (n int) {
var l int
_ = l
if m.Term != nil {
n += 1 + sovAppendEntriesRequest(uint64(*m.Term))
}
if m.PrevLogIndex != nil {
n += 1 + sovAppendEntriesRequest(uint64(*m.PrevLogIndex))
}
if m.PrevLogTerm != nil {
n += 1 + sovAppendEntriesRequest(uint64(*m.PrevLogTerm))
}
if m.CommitIndex != nil {
n += 1 + sovAppendEntriesRequest(uint64(*m.CommitIndex))
}
if m.LeaderName != nil {
l = len(*m.LeaderName)
n += 1 + l + sovAppendEntriesRequest(uint64(l))
}
if len(m.Entries) > 0 {
for _, e := range m.Entries {
l = e.Size()
n += 1 + l + sovAppendEntriesRequest(uint64(l))
}
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovAppendEntriesRequest(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozAppendEntriesRequest(x uint64) (n int) {
return sovAppendEntriesRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func NewPopulatedAppendEntriesRequest(r randyAppendEntriesRequest, easy bool) *AppendEntriesRequest {
this := &AppendEntriesRequest{}
v1 := uint64(r.Uint32())
this.Term = &v1
v2 := uint64(r.Uint32())
this.PrevLogIndex = &v2
v3 := uint64(r.Uint32())
this.PrevLogTerm = &v3
v4 := uint64(r.Uint32())
this.CommitIndex = &v4
v5 := randStringAppendEntriesRequest(r)
this.LeaderName = &v5
if r.Intn(10) != 0 {
v6 := r.Intn(10)
this.Entries = make([]*LogEntry, v6)
for i := 0; i < v6; i++ {
this.Entries[i] = NewPopulatedLogEntry(r, easy)
}
}
if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedAppendEntriesRequest(r, 7)
}
return this
}
type randyAppendEntriesRequest interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneAppendEntriesRequest(r randyAppendEntriesRequest) rune {
res := rune(r.Uint32() % 1112064)
if 55296 <= res {
res += 2047
}
return res
}
func randStringAppendEntriesRequest(r randyAppendEntriesRequest) string {
v7 := r.Intn(100)
tmps := make([]rune, v7)
for i := 0; i < v7; i++ {
tmps[i] = randUTF8RuneAppendEntriesRequest(r)
}
return string(tmps)
}
func randUnrecognizedAppendEntriesRequest(r randyAppendEntriesRequest, maxFieldNumber int) (data []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
data = randFieldAppendEntriesRequest(data, r, fieldNumber, wire)
}
return data
}
func randFieldAppendEntriesRequest(data []byte, r randyAppendEntriesRequest, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
data = encodeVarintPopulateAppendEntriesRequest(data, uint64(key))
v8 := r.Int63()
if r.Intn(2) == 0 {
v8 *= -1
}
data = encodeVarintPopulateAppendEntriesRequest(data, uint64(v8))
case 1:
data = encodeVarintPopulateAppendEntriesRequest(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
data = encodeVarintPopulateAppendEntriesRequest(data, uint64(key))
ll := r.Intn(100)
data = encodeVarintPopulateAppendEntriesRequest(data, uint64(ll))
for j := 0; j < ll; j++ {
data = append(data, byte(r.Intn(256)))
}
default:
data = encodeVarintPopulateAppendEntriesRequest(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return data
}
func encodeVarintPopulateAppendEntriesRequest(data []byte, v uint64) []byte {
for v >= 1<<7 {
data = append(data, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
data = append(data, uint8(v))
return data
}
func (m *AppendEntriesRequest) 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 *AppendEntriesRequest) MarshalTo(data []byte) (n int, err error) {
var i int
_ = i
var l int
_ = l
if m.Term != nil {
data[i] = 0x8
i++
i = encodeVarintAppendEntriesRequest(data, i, uint64(*m.Term))
}
if m.PrevLogIndex != nil {
data[i] = 0x10
i++
i = encodeVarintAppendEntriesRequest(data, i, uint64(*m.PrevLogIndex))
}
if m.PrevLogTerm != nil {
data[i] = 0x18
i++
i = encodeVarintAppendEntriesRequest(data, i, uint64(*m.PrevLogTerm))
}
if m.CommitIndex != nil {
data[i] = 0x20
i++
i = encodeVarintAppendEntriesRequest(data, i, uint64(*m.CommitIndex))
}
if m.LeaderName != nil {
data[i] = 0x2a
i++
i = encodeVarintAppendEntriesRequest(data, i, uint64(len(*m.LeaderName)))
i += copy(data[i:], *m.LeaderName)
}
if len(m.Entries) > 0 {
for _, msg := range m.Entries {
data[i] = 0x32
i++
i = encodeVarintAppendEntriesRequest(data, i, uint64(msg.Size()))
n, err := msg.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n
}
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeFixed64AppendEntriesRequest(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
data[offset+4] = uint8(v >> 32)
data[offset+5] = uint8(v >> 40)
data[offset+6] = uint8(v >> 48)
data[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32AppendEntriesRequest(data []byte, offset int, v uint32) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintAppendEntriesRequest(data []byte, offset int, v uint64) int {
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
}
func (this *AppendEntriesRequest) GoString() string {
if this == nil {
return "nil"
}
s := strings3.Join([]string{`&protobuf.AppendEntriesRequest{` + `Term:` + valueToGoStringAppendEntriesRequest(this.Term, "uint64"), `PrevLogIndex:` + valueToGoStringAppendEntriesRequest(this.PrevLogIndex, "uint64"), `PrevLogTerm:` + valueToGoStringAppendEntriesRequest(this.PrevLogTerm, "uint64"), `CommitIndex:` + valueToGoStringAppendEntriesRequest(this.CommitIndex, "uint64"), `LeaderName:` + valueToGoStringAppendEntriesRequest(this.LeaderName, "string"), `Entries:` + fmt6.Sprintf("%#v", this.Entries), `XXX_unrecognized:` + fmt6.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
return s
}
func valueToGoStringAppendEntriesRequest(v interface{}, typ string) string {
rv := reflect3.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect3.Indirect(rv).Interface()
return fmt6.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringAppendEntriesRequest(e map[int32]code_google_com_p_gogoprotobuf_proto3.Extension) string {
if e == nil {
return "nil"
}
s := "map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort1.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv1.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings3.Join(ss, ",") + "}"
return s
}
func (this *AppendEntriesRequest) VerboseEqual(that interface{}) error {
if that == nil {
if this == nil {
return nil
}
return fmt7.Errorf("that == nil && this != nil")
}
that1, ok := that.(*AppendEntriesRequest)
if !ok {
return fmt7.Errorf("that is not of type *AppendEntriesRequest")
}
if that1 == nil {
if this == nil {
return nil
}
return fmt7.Errorf("that is type *AppendEntriesRequest but is nil && this != nil")
} else if this == nil {
return fmt7.Errorf("that is type *AppendEntriesRequestbut is not nil && this == nil")
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return fmt7.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
}
} else if this.Term != nil {
return fmt7.Errorf("this.Term == nil && that.Term != nil")
} else if that1.Term != nil {
return fmt7.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
}
if this.PrevLogIndex != nil && that1.PrevLogIndex != nil {
if *this.PrevLogIndex != *that1.PrevLogIndex {
return fmt7.Errorf("PrevLogIndex this(%v) Not Equal that(%v)", *this.PrevLogIndex, *that1.PrevLogIndex)
}
} else if this.PrevLogIndex != nil {
return fmt7.Errorf("this.PrevLogIndex == nil && that.PrevLogIndex != nil")
} else if that1.PrevLogIndex != nil {
return fmt7.Errorf("PrevLogIndex this(%v) Not Equal that(%v)", this.PrevLogIndex, that1.PrevLogIndex)
}
if this.PrevLogTerm != nil && that1.PrevLogTerm != nil {
if *this.PrevLogTerm != *that1.PrevLogTerm {
return fmt7.Errorf("PrevLogTerm this(%v) Not Equal that(%v)", *this.PrevLogTerm, *that1.PrevLogTerm)
}
} else if this.PrevLogTerm != nil {
return fmt7.Errorf("this.PrevLogTerm == nil && that.PrevLogTerm != nil")
} else if that1.PrevLogTerm != nil {
return fmt7.Errorf("PrevLogTerm this(%v) Not Equal that(%v)", this.PrevLogTerm, that1.PrevLogTerm)
}
if this.CommitIndex != nil && that1.CommitIndex != nil {
if *this.CommitIndex != *that1.CommitIndex {
return fmt7.Errorf("CommitIndex this(%v) Not Equal that(%v)", *this.CommitIndex, *that1.CommitIndex)
}
} else if this.CommitIndex != nil {
return fmt7.Errorf("this.CommitIndex == nil && that.CommitIndex != nil")
} else if that1.CommitIndex != nil {
return fmt7.Errorf("CommitIndex this(%v) Not Equal that(%v)", this.CommitIndex, that1.CommitIndex)
}
if this.LeaderName != nil && that1.LeaderName != nil {
if *this.LeaderName != *that1.LeaderName {
return fmt7.Errorf("LeaderName this(%v) Not Equal that(%v)", *this.LeaderName, *that1.LeaderName)
}
} else if this.LeaderName != nil {
return fmt7.Errorf("this.LeaderName == nil && that.LeaderName != nil")
} else if that1.LeaderName != nil {
return fmt7.Errorf("LeaderName this(%v) Not Equal that(%v)", this.LeaderName, that1.LeaderName)
}
if len(this.Entries) != len(that1.Entries) {
return fmt7.Errorf("Entries this(%v) Not Equal that(%v)", len(this.Entries), len(that1.Entries))
}
for i := range this.Entries {
if !this.Entries[i].Equal(that1.Entries[i]) {
return fmt7.Errorf("Entries this[%v](%v) Not Equal that[%v](%v)", i, this.Entries[i], i, that1.Entries[i])
}
}
if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return fmt7.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
}
return nil
}
func (this *AppendEntriesRequest) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*AppendEntriesRequest)
if !ok {
return false
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return false
}
} else if this.Term != nil {
return false
} else if that1.Term != nil {
return false
}
if this.PrevLogIndex != nil && that1.PrevLogIndex != nil {
if *this.PrevLogIndex != *that1.PrevLogIndex {
return false
}
} else if this.PrevLogIndex != nil {
return false
} else if that1.PrevLogIndex != nil {
return false
}
if this.PrevLogTerm != nil && that1.PrevLogTerm != nil {
if *this.PrevLogTerm != *that1.PrevLogTerm {
return false
}
} else if this.PrevLogTerm != nil {
return false
} else if that1.PrevLogTerm != nil {
return false
}
if this.CommitIndex != nil && that1.CommitIndex != nil {
if *this.CommitIndex != *that1.CommitIndex {
return false
}
} else if this.CommitIndex != nil {
return false
} else if that1.CommitIndex != nil {
return false
}
if this.LeaderName != nil && that1.LeaderName != nil {
if *this.LeaderName != *that1.LeaderName {
return false
}
} else if this.LeaderName != nil {
return false
} else if that1.LeaderName != nil {
return false
}
if len(this.Entries) != len(that1.Entries) {
return false
}
for i := range this.Entries {
if !this.Entries[i].Equal(that1.Entries[i]) {
return false
}
}
if !bytes1.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false
}
return true
}

View File

@ -1,25 +0,0 @@
package protobuf;
import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
import "log_entry.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message AppendEntriesRequest {
required uint64 Term=1;
required uint64 PrevLogIndex=2;
required uint64 PrevLogTerm=3;
required uint64 CommitIndex=4;
required string LeaderName=5;
repeated LogEntry Entries=6;
}

View File

@ -1,553 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: append_entries_responses.proto
// DO NOT EDIT!
package protobuf
import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"
// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
import io2 "io"
import fmt8 "fmt"
import code_google_com_p_gogoprotobuf_proto4 "code.google.com/p/gogoprotobuf/proto"
import fmt9 "fmt"
import strings4 "strings"
import reflect4 "reflect"
import fmt10 "fmt"
import strings5 "strings"
import code_google_com_p_gogoprotobuf_proto5 "code.google.com/p/gogoprotobuf/proto"
import sort2 "sort"
import strconv2 "strconv"
import reflect5 "reflect"
import fmt11 "fmt"
import bytes2 "bytes"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type AppendEntriesResponse struct {
Term *uint64 `protobuf:"varint,1,req" json:"Term,omitempty"`
Index *uint64 `protobuf:"varint,2,req" json:"Index,omitempty"`
CommitIndex *uint64 `protobuf:"varint,3,req" json:"CommitIndex,omitempty"`
Success *bool `protobuf:"varint,4,req" json:"Success,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *AppendEntriesResponse) Reset() { *m = AppendEntriesResponse{} }
func (*AppendEntriesResponse) ProtoMessage() {}
func (m *AppendEntriesResponse) GetTerm() uint64 {
if m != nil && m.Term != nil {
return *m.Term
}
return 0
}
func (m *AppendEntriesResponse) GetIndex() uint64 {
if m != nil && m.Index != nil {
return *m.Index
}
return 0
}
func (m *AppendEntriesResponse) GetCommitIndex() uint64 {
if m != nil && m.CommitIndex != nil {
return *m.CommitIndex
}
return 0
}
func (m *AppendEntriesResponse) GetSuccess() bool {
if m != nil && m.Success != nil {
return *m.Success
}
return false
}
func init() {
}
func (m *AppendEntriesResponse) Unmarshal(data []byte) error {
l := len(data)
index := 0
for index < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io2.ErrUnexpectedEOF
}
b := data[index]
index++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
switch fieldNum {
case 1:
if wireType != 0 {
return fmt8.Errorf("proto: wrong wireType = %d for field Term", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io2.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Term = &v
case 2:
if wireType != 0 {
return fmt8.Errorf("proto: wrong wireType = %d for field Index", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io2.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Index = &v
case 3:
if wireType != 0 {
return fmt8.Errorf("proto: wrong wireType = %d for field CommitIndex", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io2.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.CommitIndex = &v
case 4:
if wireType != 0 {
return fmt8.Errorf("proto: wrong wireType = %d for field Success", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if index >= l {
return io2.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
b := bool(v != 0)
m.Success = &b
default:
var sizeOfWire int
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
index -= sizeOfWire
skippy, err := code_google_com_p_gogoprotobuf_proto4.Skip(data[index:])
if err != nil {
return err
}
if (index + skippy) > l {
return io2.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
index += skippy
}
}
return nil
}
func (this *AppendEntriesResponse) String() string {
if this == nil {
return "nil"
}
s := strings4.Join([]string{`&AppendEntriesResponse{`,
`Term:` + valueToStringAppendEntriesResponses(this.Term) + `,`,
`Index:` + valueToStringAppendEntriesResponses(this.Index) + `,`,
`CommitIndex:` + valueToStringAppendEntriesResponses(this.CommitIndex) + `,`,
`Success:` + valueToStringAppendEntriesResponses(this.Success) + `,`,
`XXX_unrecognized:` + fmt9.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringAppendEntriesResponses(v interface{}) string {
rv := reflect4.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect4.Indirect(rv).Interface()
return fmt9.Sprintf("*%v", pv)
}
func (m *AppendEntriesResponse) Size() (n int) {
var l int
_ = l
if m.Term != nil {
n += 1 + sovAppendEntriesResponses(uint64(*m.Term))
}
if m.Index != nil {
n += 1 + sovAppendEntriesResponses(uint64(*m.Index))
}
if m.CommitIndex != nil {
n += 1 + sovAppendEntriesResponses(uint64(*m.CommitIndex))
}
if m.Success != nil {
n += 2
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovAppendEntriesResponses(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozAppendEntriesResponses(x uint64) (n int) {
return sovAppendEntriesResponses(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func NewPopulatedAppendEntriesResponse(r randyAppendEntriesResponses, easy bool) *AppendEntriesResponse {
this := &AppendEntriesResponse{}
v1 := uint64(r.Uint32())
this.Term = &v1
v2 := uint64(r.Uint32())
this.Index = &v2
v3 := uint64(r.Uint32())
this.CommitIndex = &v3
v4 := bool(r.Intn(2) == 0)
this.Success = &v4
if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedAppendEntriesResponses(r, 5)
}
return this
}
type randyAppendEntriesResponses interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneAppendEntriesResponses(r randyAppendEntriesResponses) rune {
res := rune(r.Uint32() % 1112064)
if 55296 <= res {
res += 2047
}
return res
}
func randStringAppendEntriesResponses(r randyAppendEntriesResponses) string {
v5 := r.Intn(100)
tmps := make([]rune, v5)
for i := 0; i < v5; i++ {
tmps[i] = randUTF8RuneAppendEntriesResponses(r)
}
return string(tmps)
}
func randUnrecognizedAppendEntriesResponses(r randyAppendEntriesResponses, maxFieldNumber int) (data []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
data = randFieldAppendEntriesResponses(data, r, fieldNumber, wire)
}
return data
}
func randFieldAppendEntriesResponses(data []byte, r randyAppendEntriesResponses, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
data = encodeVarintPopulateAppendEntriesResponses(data, uint64(key))
v6 := r.Int63()
if r.Intn(2) == 0 {
v6 *= -1
}
data = encodeVarintPopulateAppendEntriesResponses(data, uint64(v6))
case 1:
data = encodeVarintPopulateAppendEntriesResponses(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
data = encodeVarintPopulateAppendEntriesResponses(data, uint64(key))
ll := r.Intn(100)
data = encodeVarintPopulateAppendEntriesResponses(data, uint64(ll))
for j := 0; j < ll; j++ {
data = append(data, byte(r.Intn(256)))
}
default:
data = encodeVarintPopulateAppendEntriesResponses(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return data
}
func encodeVarintPopulateAppendEntriesResponses(data []byte, v uint64) []byte {
for v >= 1<<7 {
data = append(data, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
data = append(data, uint8(v))
return data
}
func (m *AppendEntriesResponse) 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 *AppendEntriesResponse) MarshalTo(data []byte) (n int, err error) {
var i int
_ = i
var l int
_ = l
if m.Term != nil {
data[i] = 0x8
i++
i = encodeVarintAppendEntriesResponses(data, i, uint64(*m.Term))
}
if m.Index != nil {
data[i] = 0x10
i++
i = encodeVarintAppendEntriesResponses(data, i, uint64(*m.Index))
}
if m.CommitIndex != nil {
data[i] = 0x18
i++
i = encodeVarintAppendEntriesResponses(data, i, uint64(*m.CommitIndex))
}
if m.Success != nil {
data[i] = 0x20
i++
if *m.Success {
data[i] = 1
} else {
data[i] = 0
}
i++
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeFixed64AppendEntriesResponses(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
data[offset+4] = uint8(v >> 32)
data[offset+5] = uint8(v >> 40)
data[offset+6] = uint8(v >> 48)
data[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32AppendEntriesResponses(data []byte, offset int, v uint32) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintAppendEntriesResponses(data []byte, offset int, v uint64) int {
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
}
func (this *AppendEntriesResponse) GoString() string {
if this == nil {
return "nil"
}
s := strings5.Join([]string{`&protobuf.AppendEntriesResponse{` + `Term:` + valueToGoStringAppendEntriesResponses(this.Term, "uint64"), `Index:` + valueToGoStringAppendEntriesResponses(this.Index, "uint64"), `CommitIndex:` + valueToGoStringAppendEntriesResponses(this.CommitIndex, "uint64"), `Success:` + valueToGoStringAppendEntriesResponses(this.Success, "bool"), `XXX_unrecognized:` + fmt10.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
return s
}
func valueToGoStringAppendEntriesResponses(v interface{}, typ string) string {
rv := reflect5.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect5.Indirect(rv).Interface()
return fmt10.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringAppendEntriesResponses(e map[int32]code_google_com_p_gogoprotobuf_proto5.Extension) string {
if e == nil {
return "nil"
}
s := "map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort2.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv2.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings5.Join(ss, ",") + "}"
return s
}
func (this *AppendEntriesResponse) VerboseEqual(that interface{}) error {
if that == nil {
if this == nil {
return nil
}
return fmt11.Errorf("that == nil && this != nil")
}
that1, ok := that.(*AppendEntriesResponse)
if !ok {
return fmt11.Errorf("that is not of type *AppendEntriesResponse")
}
if that1 == nil {
if this == nil {
return nil
}
return fmt11.Errorf("that is type *AppendEntriesResponse but is nil && this != nil")
} else if this == nil {
return fmt11.Errorf("that is type *AppendEntriesResponsebut is not nil && this == nil")
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return fmt11.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
}
} else if this.Term != nil {
return fmt11.Errorf("this.Term == nil && that.Term != nil")
} else if that1.Term != nil {
return fmt11.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
}
if this.Index != nil && that1.Index != nil {
if *this.Index != *that1.Index {
return fmt11.Errorf("Index this(%v) Not Equal that(%v)", *this.Index, *that1.Index)
}
} else if this.Index != nil {
return fmt11.Errorf("this.Index == nil && that.Index != nil")
} else if that1.Index != nil {
return fmt11.Errorf("Index this(%v) Not Equal that(%v)", this.Index, that1.Index)
}
if this.CommitIndex != nil && that1.CommitIndex != nil {
if *this.CommitIndex != *that1.CommitIndex {
return fmt11.Errorf("CommitIndex this(%v) Not Equal that(%v)", *this.CommitIndex, *that1.CommitIndex)
}
} else if this.CommitIndex != nil {
return fmt11.Errorf("this.CommitIndex == nil && that.CommitIndex != nil")
} else if that1.CommitIndex != nil {
return fmt11.Errorf("CommitIndex this(%v) Not Equal that(%v)", this.CommitIndex, that1.CommitIndex)
}
if this.Success != nil && that1.Success != nil {
if *this.Success != *that1.Success {
return fmt11.Errorf("Success this(%v) Not Equal that(%v)", *this.Success, *that1.Success)
}
} else if this.Success != nil {
return fmt11.Errorf("this.Success == nil && that.Success != nil")
} else if that1.Success != nil {
return fmt11.Errorf("Success this(%v) Not Equal that(%v)", this.Success, that1.Success)
}
if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return fmt11.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
}
return nil
}
func (this *AppendEntriesResponse) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*AppendEntriesResponse)
if !ok {
return false
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return false
}
} else if this.Term != nil {
return false
} else if that1.Term != nil {
return false
}
if this.Index != nil && that1.Index != nil {
if *this.Index != *that1.Index {
return false
}
} else if this.Index != nil {
return false
} else if that1.Index != nil {
return false
}
if this.CommitIndex != nil && that1.CommitIndex != nil {
if *this.CommitIndex != *that1.CommitIndex {
return false
}
} else if this.CommitIndex != nil {
return false
} else if that1.CommitIndex != nil {
return false
}
if this.Success != nil && that1.Success != nil {
if *this.Success != *that1.Success {
return false
}
} else if this.Success != nil {
return false
} else if that1.Success != nil {
return false
}
if !bytes2.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false
}
return true
}

View File

@ -1,22 +0,0 @@
package protobuf;
import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message AppendEntriesResponse {
required uint64 Term=1;
required uint64 Index=2;
required uint64 CommitIndex=3;
required bool Success=4;
}

View File

@ -1,555 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: log_entry.proto
// DO NOT EDIT!
package protobuf
import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"
// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
import io "io"
import fmt "fmt"
import code_google_com_p_gogoprotobuf_proto "code.google.com/p/gogoprotobuf/proto"
import fmt1 "fmt"
import strings "strings"
import reflect "reflect"
import fmt2 "fmt"
import strings1 "strings"
import code_google_com_p_gogoprotobuf_proto1 "code.google.com/p/gogoprotobuf/proto"
import sort "sort"
import strconv "strconv"
import reflect1 "reflect"
import fmt3 "fmt"
import bytes "bytes"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type LogEntry struct {
Index *uint64 `protobuf:"varint,1,req" json:"Index,omitempty"`
Term *uint64 `protobuf:"varint,2,req" json:"Term,omitempty"`
CommandName *string `protobuf:"bytes,3,req" json:"CommandName,omitempty"`
Command []byte `protobuf:"bytes,4,opt" json:"Command,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *LogEntry) Reset() { *m = LogEntry{} }
func (*LogEntry) ProtoMessage() {}
func (m *LogEntry) GetIndex() uint64 {
if m != nil && m.Index != nil {
return *m.Index
}
return 0
}
func (m *LogEntry) GetTerm() uint64 {
if m != nil && m.Term != nil {
return *m.Term
}
return 0
}
func (m *LogEntry) GetCommandName() string {
if m != nil && m.CommandName != nil {
return *m.CommandName
}
return ""
}
func (m *LogEntry) GetCommand() []byte {
if m != nil {
return m.Command
}
return nil
}
func init() {
}
func (m *LogEntry) Unmarshal(data []byte) error {
l := len(data)
index := 0
for index < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
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)
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Index = &v
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Term", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Term = &v
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field CommandName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io.ErrUnexpectedEOF
}
b := data[index]
index++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + int(stringLen)
if postIndex > l {
return io.ErrUnexpectedEOF
}
s := string(data[index:postIndex])
m.CommandName = &s
index = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Command", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if index >= l {
return io.ErrUnexpectedEOF
}
b := data[index]
index++
byteLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + byteLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Command = append(m.Command, data[index:postIndex]...)
index = postIndex
default:
var sizeOfWire int
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
index -= sizeOfWire
skippy, err := code_google_com_p_gogoprotobuf_proto.Skip(data[index:])
if err != nil {
return err
}
if (index + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
index += skippy
}
}
return nil
}
func (this *LogEntry) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&LogEntry{`,
`Index:` + valueToStringLogEntry(this.Index) + `,`,
`Term:` + valueToStringLogEntry(this.Term) + `,`,
`CommandName:` + valueToStringLogEntry(this.CommandName) + `,`,
`Command:` + valueToStringLogEntry(this.Command) + `,`,
`XXX_unrecognized:` + fmt1.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringLogEntry(v interface{}) string {
rv := reflect.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect.Indirect(rv).Interface()
return fmt1.Sprintf("*%v", pv)
}
func (m *LogEntry) Size() (n int) {
var l int
_ = l
if m.Index != nil {
n += 1 + sovLogEntry(uint64(*m.Index))
}
if m.Term != nil {
n += 1 + sovLogEntry(uint64(*m.Term))
}
if m.CommandName != nil {
l = len(*m.CommandName)
n += 1 + l + sovLogEntry(uint64(l))
}
if m.Command != nil {
l = len(m.Command)
n += 1 + l + sovLogEntry(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovLogEntry(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozLogEntry(x uint64) (n int) {
return sovLogEntry(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func NewPopulatedLogEntry(r randyLogEntry, easy bool) *LogEntry {
this := &LogEntry{}
v1 := uint64(r.Uint32())
this.Index = &v1
v2 := uint64(r.Uint32())
this.Term = &v2
v3 := randStringLogEntry(r)
this.CommandName = &v3
if r.Intn(10) != 0 {
v4 := r.Intn(100)
this.Command = make([]byte, v4)
for i := 0; i < v4; i++ {
this.Command[i] = byte(r.Intn(256))
}
}
if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedLogEntry(r, 5)
}
return this
}
type randyLogEntry interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneLogEntry(r randyLogEntry) rune {
res := rune(r.Uint32() % 1112064)
if 55296 <= res {
res += 2047
}
return res
}
func randStringLogEntry(r randyLogEntry) string {
v5 := r.Intn(100)
tmps := make([]rune, v5)
for i := 0; i < v5; i++ {
tmps[i] = randUTF8RuneLogEntry(r)
}
return string(tmps)
}
func randUnrecognizedLogEntry(r randyLogEntry, maxFieldNumber int) (data []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
data = randFieldLogEntry(data, r, fieldNumber, wire)
}
return data
}
func randFieldLogEntry(data []byte, r randyLogEntry, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
data = encodeVarintPopulateLogEntry(data, uint64(key))
v6 := r.Int63()
if r.Intn(2) == 0 {
v6 *= -1
}
data = encodeVarintPopulateLogEntry(data, uint64(v6))
case 1:
data = encodeVarintPopulateLogEntry(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
data = encodeVarintPopulateLogEntry(data, uint64(key))
ll := r.Intn(100)
data = encodeVarintPopulateLogEntry(data, uint64(ll))
for j := 0; j < ll; j++ {
data = append(data, byte(r.Intn(256)))
}
default:
data = encodeVarintPopulateLogEntry(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return data
}
func encodeVarintPopulateLogEntry(data []byte, v uint64) []byte {
for v >= 1<<7 {
data = append(data, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
data = append(data, uint8(v))
return data
}
func (m *LogEntry) 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 *LogEntry) MarshalTo(data []byte) (n int, err error) {
var i int
_ = i
var l int
_ = l
if m.Index != nil {
data[i] = 0x8
i++
i = encodeVarintLogEntry(data, i, uint64(*m.Index))
}
if m.Term != nil {
data[i] = 0x10
i++
i = encodeVarintLogEntry(data, i, uint64(*m.Term))
}
if m.CommandName != nil {
data[i] = 0x1a
i++
i = encodeVarintLogEntry(data, i, uint64(len(*m.CommandName)))
i += copy(data[i:], *m.CommandName)
}
if m.Command != nil {
data[i] = 0x22
i++
i = encodeVarintLogEntry(data, i, uint64(len(m.Command)))
i += copy(data[i:], m.Command)
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeFixed64LogEntry(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
data[offset+4] = uint8(v >> 32)
data[offset+5] = uint8(v >> 40)
data[offset+6] = uint8(v >> 48)
data[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32LogEntry(data []byte, offset int, v uint32) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintLogEntry(data []byte, offset int, v uint64) int {
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
}
func (this *LogEntry) GoString() string {
if this == nil {
return "nil"
}
s := strings1.Join([]string{`&protobuf.LogEntry{` + `Index:` + valueToGoStringLogEntry(this.Index, "uint64"), `Term:` + valueToGoStringLogEntry(this.Term, "uint64"), `CommandName:` + valueToGoStringLogEntry(this.CommandName, "string"), `Command:` + valueToGoStringLogEntry(this.Command, "byte"), `XXX_unrecognized:` + fmt2.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
return s
}
func valueToGoStringLogEntry(v interface{}, typ string) string {
rv := reflect1.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect1.Indirect(rv).Interface()
return fmt2.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringLogEntry(e map[int32]code_google_com_p_gogoprotobuf_proto1.Extension) string {
if e == nil {
return "nil"
}
s := "map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings1.Join(ss, ",") + "}"
return s
}
func (this *LogEntry) VerboseEqual(that interface{}) error {
if that == nil {
if this == nil {
return nil
}
return fmt3.Errorf("that == nil && this != nil")
}
that1, ok := that.(*LogEntry)
if !ok {
return fmt3.Errorf("that is not of type *LogEntry")
}
if that1 == nil {
if this == nil {
return nil
}
return fmt3.Errorf("that is type *LogEntry but is nil && this != nil")
} else if this == nil {
return fmt3.Errorf("that is type *LogEntrybut is not nil && this == nil")
}
if this.Index != nil && that1.Index != nil {
if *this.Index != *that1.Index {
return fmt3.Errorf("Index this(%v) Not Equal that(%v)", *this.Index, *that1.Index)
}
} else if this.Index != nil {
return fmt3.Errorf("this.Index == nil && that.Index != nil")
} else if that1.Index != nil {
return fmt3.Errorf("Index this(%v) Not Equal that(%v)", this.Index, that1.Index)
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return fmt3.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
}
} else if this.Term != nil {
return fmt3.Errorf("this.Term == nil && that.Term != nil")
} else if that1.Term != nil {
return fmt3.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
}
if this.CommandName != nil && that1.CommandName != nil {
if *this.CommandName != *that1.CommandName {
return fmt3.Errorf("CommandName this(%v) Not Equal that(%v)", *this.CommandName, *that1.CommandName)
}
} else if this.CommandName != nil {
return fmt3.Errorf("this.CommandName == nil && that.CommandName != nil")
} else if that1.CommandName != nil {
return fmt3.Errorf("CommandName this(%v) Not Equal that(%v)", this.CommandName, that1.CommandName)
}
if !bytes.Equal(this.Command, that1.Command) {
return fmt3.Errorf("Command this(%v) Not Equal that(%v)", this.Command, that1.Command)
}
if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return fmt3.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
}
return nil
}
func (this *LogEntry) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*LogEntry)
if !ok {
return false
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.Index != nil && that1.Index != nil {
if *this.Index != *that1.Index {
return false
}
} else if this.Index != nil {
return false
} else if that1.Index != nil {
return false
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return false
}
} else if this.Term != nil {
return false
} else if that1.Term != nil {
return false
}
if this.CommandName != nil && that1.CommandName != nil {
if *this.CommandName != *that1.CommandName {
return false
}
} else if this.CommandName != nil {
return false
} else if that1.CommandName != nil {
return false
}
if !bytes.Equal(this.Command, that1.Command) {
return false
}
if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false
}
return true
}

View File

@ -1,22 +0,0 @@
package protobuf;
import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message LogEntry {
required uint64 Index=1;
required uint64 Term=2;
required string CommandName=3;
optional bytes Command=4; // for nop-command
}

View File

@ -1,555 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: request_vote_request.proto
// DO NOT EDIT!
package protobuf
import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"
// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
import io3 "io"
import fmt12 "fmt"
import code_google_com_p_gogoprotobuf_proto6 "code.google.com/p/gogoprotobuf/proto"
import fmt13 "fmt"
import strings6 "strings"
import reflect6 "reflect"
import fmt14 "fmt"
import strings7 "strings"
import code_google_com_p_gogoprotobuf_proto7 "code.google.com/p/gogoprotobuf/proto"
import sort3 "sort"
import strconv3 "strconv"
import reflect7 "reflect"
import fmt15 "fmt"
import bytes3 "bytes"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type RequestVoteRequest struct {
Term *uint64 `protobuf:"varint,1,req" json:"Term,omitempty"`
LastLogIndex *uint64 `protobuf:"varint,2,req" json:"LastLogIndex,omitempty"`
LastLogTerm *uint64 `protobuf:"varint,3,req" json:"LastLogTerm,omitempty"`
CandidateName *string `protobuf:"bytes,4,req" json:"CandidateName,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RequestVoteRequest) Reset() { *m = RequestVoteRequest{} }
func (*RequestVoteRequest) ProtoMessage() {}
func (m *RequestVoteRequest) GetTerm() uint64 {
if m != nil && m.Term != nil {
return *m.Term
}
return 0
}
func (m *RequestVoteRequest) GetLastLogIndex() uint64 {
if m != nil && m.LastLogIndex != nil {
return *m.LastLogIndex
}
return 0
}
func (m *RequestVoteRequest) GetLastLogTerm() uint64 {
if m != nil && m.LastLogTerm != nil {
return *m.LastLogTerm
}
return 0
}
func (m *RequestVoteRequest) GetCandidateName() string {
if m != nil && m.CandidateName != nil {
return *m.CandidateName
}
return ""
}
func init() {
}
func (m *RequestVoteRequest) Unmarshal(data []byte) error {
l := len(data)
index := 0
for index < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io3.ErrUnexpectedEOF
}
b := data[index]
index++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
switch fieldNum {
case 1:
if wireType != 0 {
return fmt12.Errorf("proto: wrong wireType = %d for field Term", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io3.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Term = &v
case 2:
if wireType != 0 {
return fmt12.Errorf("proto: wrong wireType = %d for field LastLogIndex", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io3.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.LastLogIndex = &v
case 3:
if wireType != 0 {
return fmt12.Errorf("proto: wrong wireType = %d for field LastLogTerm", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io3.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.LastLogTerm = &v
case 4:
if wireType != 2 {
return fmt12.Errorf("proto: wrong wireType = %d for field CandidateName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io3.ErrUnexpectedEOF
}
b := data[index]
index++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + int(stringLen)
if postIndex > l {
return io3.ErrUnexpectedEOF
}
s := string(data[index:postIndex])
m.CandidateName = &s
index = postIndex
default:
var sizeOfWire int
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
index -= sizeOfWire
skippy, err := code_google_com_p_gogoprotobuf_proto6.Skip(data[index:])
if err != nil {
return err
}
if (index + skippy) > l {
return io3.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
index += skippy
}
}
return nil
}
func (this *RequestVoteRequest) String() string {
if this == nil {
return "nil"
}
s := strings6.Join([]string{`&RequestVoteRequest{`,
`Term:` + valueToStringRequestVoteRequest(this.Term) + `,`,
`LastLogIndex:` + valueToStringRequestVoteRequest(this.LastLogIndex) + `,`,
`LastLogTerm:` + valueToStringRequestVoteRequest(this.LastLogTerm) + `,`,
`CandidateName:` + valueToStringRequestVoteRequest(this.CandidateName) + `,`,
`XXX_unrecognized:` + fmt13.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringRequestVoteRequest(v interface{}) string {
rv := reflect6.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect6.Indirect(rv).Interface()
return fmt13.Sprintf("*%v", pv)
}
func (m *RequestVoteRequest) Size() (n int) {
var l int
_ = l
if m.Term != nil {
n += 1 + sovRequestVoteRequest(uint64(*m.Term))
}
if m.LastLogIndex != nil {
n += 1 + sovRequestVoteRequest(uint64(*m.LastLogIndex))
}
if m.LastLogTerm != nil {
n += 1 + sovRequestVoteRequest(uint64(*m.LastLogTerm))
}
if m.CandidateName != nil {
l = len(*m.CandidateName)
n += 1 + l + sovRequestVoteRequest(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovRequestVoteRequest(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozRequestVoteRequest(x uint64) (n int) {
return sovRequestVoteRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func NewPopulatedRequestVoteRequest(r randyRequestVoteRequest, easy bool) *RequestVoteRequest {
this := &RequestVoteRequest{}
v1 := uint64(r.Uint32())
this.Term = &v1
v2 := uint64(r.Uint32())
this.LastLogIndex = &v2
v3 := uint64(r.Uint32())
this.LastLogTerm = &v3
v4 := randStringRequestVoteRequest(r)
this.CandidateName = &v4
if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedRequestVoteRequest(r, 5)
}
return this
}
type randyRequestVoteRequest interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneRequestVoteRequest(r randyRequestVoteRequest) rune {
res := rune(r.Uint32() % 1112064)
if 55296 <= res {
res += 2047
}
return res
}
func randStringRequestVoteRequest(r randyRequestVoteRequest) string {
v5 := r.Intn(100)
tmps := make([]rune, v5)
for i := 0; i < v5; i++ {
tmps[i] = randUTF8RuneRequestVoteRequest(r)
}
return string(tmps)
}
func randUnrecognizedRequestVoteRequest(r randyRequestVoteRequest, maxFieldNumber int) (data []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
data = randFieldRequestVoteRequest(data, r, fieldNumber, wire)
}
return data
}
func randFieldRequestVoteRequest(data []byte, r randyRequestVoteRequest, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
data = encodeVarintPopulateRequestVoteRequest(data, uint64(key))
v6 := r.Int63()
if r.Intn(2) == 0 {
v6 *= -1
}
data = encodeVarintPopulateRequestVoteRequest(data, uint64(v6))
case 1:
data = encodeVarintPopulateRequestVoteRequest(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
data = encodeVarintPopulateRequestVoteRequest(data, uint64(key))
ll := r.Intn(100)
data = encodeVarintPopulateRequestVoteRequest(data, uint64(ll))
for j := 0; j < ll; j++ {
data = append(data, byte(r.Intn(256)))
}
default:
data = encodeVarintPopulateRequestVoteRequest(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return data
}
func encodeVarintPopulateRequestVoteRequest(data []byte, v uint64) []byte {
for v >= 1<<7 {
data = append(data, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
data = append(data, uint8(v))
return data
}
func (m *RequestVoteRequest) 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 *RequestVoteRequest) MarshalTo(data []byte) (n int, err error) {
var i int
_ = i
var l int
_ = l
if m.Term != nil {
data[i] = 0x8
i++
i = encodeVarintRequestVoteRequest(data, i, uint64(*m.Term))
}
if m.LastLogIndex != nil {
data[i] = 0x10
i++
i = encodeVarintRequestVoteRequest(data, i, uint64(*m.LastLogIndex))
}
if m.LastLogTerm != nil {
data[i] = 0x18
i++
i = encodeVarintRequestVoteRequest(data, i, uint64(*m.LastLogTerm))
}
if m.CandidateName != nil {
data[i] = 0x22
i++
i = encodeVarintRequestVoteRequest(data, i, uint64(len(*m.CandidateName)))
i += copy(data[i:], *m.CandidateName)
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeFixed64RequestVoteRequest(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
data[offset+4] = uint8(v >> 32)
data[offset+5] = uint8(v >> 40)
data[offset+6] = uint8(v >> 48)
data[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32RequestVoteRequest(data []byte, offset int, v uint32) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintRequestVoteRequest(data []byte, offset int, v uint64) int {
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
}
func (this *RequestVoteRequest) GoString() string {
if this == nil {
return "nil"
}
s := strings7.Join([]string{`&protobuf.RequestVoteRequest{` + `Term:` + valueToGoStringRequestVoteRequest(this.Term, "uint64"), `LastLogIndex:` + valueToGoStringRequestVoteRequest(this.LastLogIndex, "uint64"), `LastLogTerm:` + valueToGoStringRequestVoteRequest(this.LastLogTerm, "uint64"), `CandidateName:` + valueToGoStringRequestVoteRequest(this.CandidateName, "string"), `XXX_unrecognized:` + fmt14.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
return s
}
func valueToGoStringRequestVoteRequest(v interface{}, typ string) string {
rv := reflect7.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect7.Indirect(rv).Interface()
return fmt14.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringRequestVoteRequest(e map[int32]code_google_com_p_gogoprotobuf_proto7.Extension) string {
if e == nil {
return "nil"
}
s := "map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort3.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv3.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings7.Join(ss, ",") + "}"
return s
}
func (this *RequestVoteRequest) VerboseEqual(that interface{}) error {
if that == nil {
if this == nil {
return nil
}
return fmt15.Errorf("that == nil && this != nil")
}
that1, ok := that.(*RequestVoteRequest)
if !ok {
return fmt15.Errorf("that is not of type *RequestVoteRequest")
}
if that1 == nil {
if this == nil {
return nil
}
return fmt15.Errorf("that is type *RequestVoteRequest but is nil && this != nil")
} else if this == nil {
return fmt15.Errorf("that is type *RequestVoteRequestbut is not nil && this == nil")
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return fmt15.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
}
} else if this.Term != nil {
return fmt15.Errorf("this.Term == nil && that.Term != nil")
} else if that1.Term != nil {
return fmt15.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
}
if this.LastLogIndex != nil && that1.LastLogIndex != nil {
if *this.LastLogIndex != *that1.LastLogIndex {
return fmt15.Errorf("LastLogIndex this(%v) Not Equal that(%v)", *this.LastLogIndex, *that1.LastLogIndex)
}
} else if this.LastLogIndex != nil {
return fmt15.Errorf("this.LastLogIndex == nil && that.LastLogIndex != nil")
} else if that1.LastLogIndex != nil {
return fmt15.Errorf("LastLogIndex this(%v) Not Equal that(%v)", this.LastLogIndex, that1.LastLogIndex)
}
if this.LastLogTerm != nil && that1.LastLogTerm != nil {
if *this.LastLogTerm != *that1.LastLogTerm {
return fmt15.Errorf("LastLogTerm this(%v) Not Equal that(%v)", *this.LastLogTerm, *that1.LastLogTerm)
}
} else if this.LastLogTerm != nil {
return fmt15.Errorf("this.LastLogTerm == nil && that.LastLogTerm != nil")
} else if that1.LastLogTerm != nil {
return fmt15.Errorf("LastLogTerm this(%v) Not Equal that(%v)", this.LastLogTerm, that1.LastLogTerm)
}
if this.CandidateName != nil && that1.CandidateName != nil {
if *this.CandidateName != *that1.CandidateName {
return fmt15.Errorf("CandidateName this(%v) Not Equal that(%v)", *this.CandidateName, *that1.CandidateName)
}
} else if this.CandidateName != nil {
return fmt15.Errorf("this.CandidateName == nil && that.CandidateName != nil")
} else if that1.CandidateName != nil {
return fmt15.Errorf("CandidateName this(%v) Not Equal that(%v)", this.CandidateName, that1.CandidateName)
}
if !bytes3.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return fmt15.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
}
return nil
}
func (this *RequestVoteRequest) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*RequestVoteRequest)
if !ok {
return false
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return false
}
} else if this.Term != nil {
return false
} else if that1.Term != nil {
return false
}
if this.LastLogIndex != nil && that1.LastLogIndex != nil {
if *this.LastLogIndex != *that1.LastLogIndex {
return false
}
} else if this.LastLogIndex != nil {
return false
} else if that1.LastLogIndex != nil {
return false
}
if this.LastLogTerm != nil && that1.LastLogTerm != nil {
if *this.LastLogTerm != *that1.LastLogTerm {
return false
}
} else if this.LastLogTerm != nil {
return false
} else if that1.LastLogTerm != nil {
return false
}
if this.CandidateName != nil && that1.CandidateName != nil {
if *this.CandidateName != *that1.CandidateName {
return false
}
} else if this.CandidateName != nil {
return false
} else if that1.CandidateName != nil {
return false
}
if !bytes3.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false
}
return true
}

View File

@ -1,22 +0,0 @@
package protobuf;
import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message RequestVoteRequest {
required uint64 Term=1;
required uint64 LastLogIndex=2;
required uint64 LastLogTerm=3;
required string CandidateName=4;
}

View File

@ -1,445 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: request_vote_responses.proto
// DO NOT EDIT!
package protobuf
import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"
// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
import io4 "io"
import fmt16 "fmt"
import code_google_com_p_gogoprotobuf_proto8 "code.google.com/p/gogoprotobuf/proto"
import fmt17 "fmt"
import strings8 "strings"
import reflect8 "reflect"
import fmt18 "fmt"
import strings9 "strings"
import code_google_com_p_gogoprotobuf_proto9 "code.google.com/p/gogoprotobuf/proto"
import sort4 "sort"
import strconv4 "strconv"
import reflect9 "reflect"
import fmt19 "fmt"
import bytes4 "bytes"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type RequestVoteResponse struct {
Term *uint64 `protobuf:"varint,1,req" json:"Term,omitempty"`
VoteGranted *bool `protobuf:"varint,2,req" json:"VoteGranted,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RequestVoteResponse) Reset() { *m = RequestVoteResponse{} }
func (*RequestVoteResponse) ProtoMessage() {}
func (m *RequestVoteResponse) GetTerm() uint64 {
if m != nil && m.Term != nil {
return *m.Term
}
return 0
}
func (m *RequestVoteResponse) GetVoteGranted() bool {
if m != nil && m.VoteGranted != nil {
return *m.VoteGranted
}
return false
}
func init() {
}
func (m *RequestVoteResponse) Unmarshal(data []byte) error {
l := len(data)
index := 0
for index < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io4.ErrUnexpectedEOF
}
b := data[index]
index++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
switch fieldNum {
case 1:
if wireType != 0 {
return fmt16.Errorf("proto: wrong wireType = %d for field Term", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io4.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Term = &v
case 2:
if wireType != 0 {
return fmt16.Errorf("proto: wrong wireType = %d for field VoteGranted", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if index >= l {
return io4.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
b := bool(v != 0)
m.VoteGranted = &b
default:
var sizeOfWire int
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
index -= sizeOfWire
skippy, err := code_google_com_p_gogoprotobuf_proto8.Skip(data[index:])
if err != nil {
return err
}
if (index + skippy) > l {
return io4.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
index += skippy
}
}
return nil
}
func (this *RequestVoteResponse) String() string {
if this == nil {
return "nil"
}
s := strings8.Join([]string{`&RequestVoteResponse{`,
`Term:` + valueToStringRequestVoteResponses(this.Term) + `,`,
`VoteGranted:` + valueToStringRequestVoteResponses(this.VoteGranted) + `,`,
`XXX_unrecognized:` + fmt17.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringRequestVoteResponses(v interface{}) string {
rv := reflect8.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect8.Indirect(rv).Interface()
return fmt17.Sprintf("*%v", pv)
}
func (m *RequestVoteResponse) Size() (n int) {
var l int
_ = l
if m.Term != nil {
n += 1 + sovRequestVoteResponses(uint64(*m.Term))
}
if m.VoteGranted != nil {
n += 2
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovRequestVoteResponses(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozRequestVoteResponses(x uint64) (n int) {
return sovRequestVoteResponses(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func NewPopulatedRequestVoteResponse(r randyRequestVoteResponses, easy bool) *RequestVoteResponse {
this := &RequestVoteResponse{}
v1 := uint64(r.Uint32())
this.Term = &v1
v2 := bool(r.Intn(2) == 0)
this.VoteGranted = &v2
if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedRequestVoteResponses(r, 3)
}
return this
}
type randyRequestVoteResponses interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneRequestVoteResponses(r randyRequestVoteResponses) rune {
res := rune(r.Uint32() % 1112064)
if 55296 <= res {
res += 2047
}
return res
}
func randStringRequestVoteResponses(r randyRequestVoteResponses) string {
v3 := r.Intn(100)
tmps := make([]rune, v3)
for i := 0; i < v3; i++ {
tmps[i] = randUTF8RuneRequestVoteResponses(r)
}
return string(tmps)
}
func randUnrecognizedRequestVoteResponses(r randyRequestVoteResponses, maxFieldNumber int) (data []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
data = randFieldRequestVoteResponses(data, r, fieldNumber, wire)
}
return data
}
func randFieldRequestVoteResponses(data []byte, r randyRequestVoteResponses, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
data = encodeVarintPopulateRequestVoteResponses(data, uint64(key))
v4 := r.Int63()
if r.Intn(2) == 0 {
v4 *= -1
}
data = encodeVarintPopulateRequestVoteResponses(data, uint64(v4))
case 1:
data = encodeVarintPopulateRequestVoteResponses(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
data = encodeVarintPopulateRequestVoteResponses(data, uint64(key))
ll := r.Intn(100)
data = encodeVarintPopulateRequestVoteResponses(data, uint64(ll))
for j := 0; j < ll; j++ {
data = append(data, byte(r.Intn(256)))
}
default:
data = encodeVarintPopulateRequestVoteResponses(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return data
}
func encodeVarintPopulateRequestVoteResponses(data []byte, v uint64) []byte {
for v >= 1<<7 {
data = append(data, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
data = append(data, uint8(v))
return data
}
func (m *RequestVoteResponse) 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 *RequestVoteResponse) MarshalTo(data []byte) (n int, err error) {
var i int
_ = i
var l int
_ = l
if m.Term != nil {
data[i] = 0x8
i++
i = encodeVarintRequestVoteResponses(data, i, uint64(*m.Term))
}
if m.VoteGranted != nil {
data[i] = 0x10
i++
if *m.VoteGranted {
data[i] = 1
} else {
data[i] = 0
}
i++
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeFixed64RequestVoteResponses(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
data[offset+4] = uint8(v >> 32)
data[offset+5] = uint8(v >> 40)
data[offset+6] = uint8(v >> 48)
data[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32RequestVoteResponses(data []byte, offset int, v uint32) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintRequestVoteResponses(data []byte, offset int, v uint64) int {
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
}
func (this *RequestVoteResponse) GoString() string {
if this == nil {
return "nil"
}
s := strings9.Join([]string{`&protobuf.RequestVoteResponse{` + `Term:` + valueToGoStringRequestVoteResponses(this.Term, "uint64"), `VoteGranted:` + valueToGoStringRequestVoteResponses(this.VoteGranted, "bool"), `XXX_unrecognized:` + fmt18.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
return s
}
func valueToGoStringRequestVoteResponses(v interface{}, typ string) string {
rv := reflect9.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect9.Indirect(rv).Interface()
return fmt18.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringRequestVoteResponses(e map[int32]code_google_com_p_gogoprotobuf_proto9.Extension) string {
if e == nil {
return "nil"
}
s := "map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort4.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv4.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings9.Join(ss, ",") + "}"
return s
}
func (this *RequestVoteResponse) VerboseEqual(that interface{}) error {
if that == nil {
if this == nil {
return nil
}
return fmt19.Errorf("that == nil && this != nil")
}
that1, ok := that.(*RequestVoteResponse)
if !ok {
return fmt19.Errorf("that is not of type *RequestVoteResponse")
}
if that1 == nil {
if this == nil {
return nil
}
return fmt19.Errorf("that is type *RequestVoteResponse but is nil && this != nil")
} else if this == nil {
return fmt19.Errorf("that is type *RequestVoteResponsebut is not nil && this == nil")
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return fmt19.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
}
} else if this.Term != nil {
return fmt19.Errorf("this.Term == nil && that.Term != nil")
} else if that1.Term != nil {
return fmt19.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
}
if this.VoteGranted != nil && that1.VoteGranted != nil {
if *this.VoteGranted != *that1.VoteGranted {
return fmt19.Errorf("VoteGranted this(%v) Not Equal that(%v)", *this.VoteGranted, *that1.VoteGranted)
}
} else if this.VoteGranted != nil {
return fmt19.Errorf("this.VoteGranted == nil && that.VoteGranted != nil")
} else if that1.VoteGranted != nil {
return fmt19.Errorf("VoteGranted this(%v) Not Equal that(%v)", this.VoteGranted, that1.VoteGranted)
}
if !bytes4.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return fmt19.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
}
return nil
}
func (this *RequestVoteResponse) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*RequestVoteResponse)
if !ok {
return false
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return false
}
} else if this.Term != nil {
return false
} else if that1.Term != nil {
return false
}
if this.VoteGranted != nil && that1.VoteGranted != nil {
if *this.VoteGranted != *that1.VoteGranted {
return false
}
} else if this.VoteGranted != nil {
return false
} else if that1.VoteGranted != nil {
return false
}
if !bytes4.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false
}
return true
}

View File

@ -1,20 +0,0 @@
package protobuf;
import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message RequestVoteResponse {
required uint64 Term=1;
required bool VoteGranted=2;
}

View File

@ -1,902 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: snapshot_recovery_request.proto
// DO NOT EDIT!
package protobuf
import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"
// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
import io5 "io"
import fmt20 "fmt"
import code_google_com_p_gogoprotobuf_proto10 "code.google.com/p/gogoprotobuf/proto"
import fmt21 "fmt"
import strings10 "strings"
import reflect10 "reflect"
import fmt22 "fmt"
import strings11 "strings"
import code_google_com_p_gogoprotobuf_proto11 "code.google.com/p/gogoprotobuf/proto"
import sort5 "sort"
import strconv5 "strconv"
import reflect11 "reflect"
import fmt23 "fmt"
import bytes5 "bytes"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type SnapshotRecoveryRequest struct {
LeaderName *string `protobuf:"bytes,1,req" json:"LeaderName,omitempty"`
LastIndex *uint64 `protobuf:"varint,2,req" json:"LastIndex,omitempty"`
LastTerm *uint64 `protobuf:"varint,3,req" json:"LastTerm,omitempty"`
Peers []*SnapshotRecoveryRequest_Peer `protobuf:"bytes,4,rep" json:"Peers,omitempty"`
State []byte `protobuf:"bytes,5,req" json:"State,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotRecoveryRequest) Reset() { *m = SnapshotRecoveryRequest{} }
func (*SnapshotRecoveryRequest) ProtoMessage() {}
func (m *SnapshotRecoveryRequest) GetLeaderName() string {
if m != nil && m.LeaderName != nil {
return *m.LeaderName
}
return ""
}
func (m *SnapshotRecoveryRequest) GetLastIndex() uint64 {
if m != nil && m.LastIndex != nil {
return *m.LastIndex
}
return 0
}
func (m *SnapshotRecoveryRequest) GetLastTerm() uint64 {
if m != nil && m.LastTerm != nil {
return *m.LastTerm
}
return 0
}
func (m *SnapshotRecoveryRequest) GetPeers() []*SnapshotRecoveryRequest_Peer {
if m != nil {
return m.Peers
}
return nil
}
func (m *SnapshotRecoveryRequest) GetState() []byte {
if m != nil {
return m.State
}
return nil
}
type SnapshotRecoveryRequest_Peer struct {
Name *string `protobuf:"bytes,1,req" json:"Name,omitempty"`
ConnectionString *string `protobuf:"bytes,2,req" json:"ConnectionString,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotRecoveryRequest_Peer) Reset() { *m = SnapshotRecoveryRequest_Peer{} }
func (*SnapshotRecoveryRequest_Peer) ProtoMessage() {}
func (m *SnapshotRecoveryRequest_Peer) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *SnapshotRecoveryRequest_Peer) GetConnectionString() string {
if m != nil && m.ConnectionString != nil {
return *m.ConnectionString
}
return ""
}
func init() {
}
func (m *SnapshotRecoveryRequest) Unmarshal(data []byte) error {
l := len(data)
index := 0
for index < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io5.ErrUnexpectedEOF
}
b := data[index]
index++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
switch fieldNum {
case 1:
if wireType != 2 {
return fmt20.Errorf("proto: wrong wireType = %d for field LeaderName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io5.ErrUnexpectedEOF
}
b := data[index]
index++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + int(stringLen)
if postIndex > l {
return io5.ErrUnexpectedEOF
}
s := string(data[index:postIndex])
m.LeaderName = &s
index = postIndex
case 2:
if wireType != 0 {
return fmt20.Errorf("proto: wrong wireType = %d for field LastIndex", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io5.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.LastIndex = &v
case 3:
if wireType != 0 {
return fmt20.Errorf("proto: wrong wireType = %d for field LastTerm", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io5.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.LastTerm = &v
case 4:
if wireType != 2 {
return fmt20.Errorf("proto: wrong wireType = %d for field Peers", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if index >= l {
return io5.ErrUnexpectedEOF
}
b := data[index]
index++
msglen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + msglen
if postIndex > l {
return io5.ErrUnexpectedEOF
}
m.Peers = append(m.Peers, &SnapshotRecoveryRequest_Peer{})
m.Peers[len(m.Peers)-1].Unmarshal(data[index:postIndex])
index = postIndex
case 5:
if wireType != 2 {
return fmt20.Errorf("proto: wrong wireType = %d for field State", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if index >= l {
return io5.ErrUnexpectedEOF
}
b := data[index]
index++
byteLen |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + byteLen
if postIndex > l {
return io5.ErrUnexpectedEOF
}
m.State = append(m.State, data[index:postIndex]...)
index = postIndex
default:
var sizeOfWire int
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
index -= sizeOfWire
skippy, err := code_google_com_p_gogoprotobuf_proto10.Skip(data[index:])
if err != nil {
return err
}
if (index + skippy) > l {
return io5.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
index += skippy
}
}
return nil
}
func (m *SnapshotRecoveryRequest_Peer) Unmarshal(data []byte) error {
l := len(data)
index := 0
for index < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io5.ErrUnexpectedEOF
}
b := data[index]
index++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
switch fieldNum {
case 1:
if wireType != 2 {
return fmt20.Errorf("proto: wrong wireType = %d for field Name", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io5.ErrUnexpectedEOF
}
b := data[index]
index++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + int(stringLen)
if postIndex > l {
return io5.ErrUnexpectedEOF
}
s := string(data[index:postIndex])
m.Name = &s
index = postIndex
case 2:
if wireType != 2 {
return fmt20.Errorf("proto: wrong wireType = %d for field ConnectionString", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io5.ErrUnexpectedEOF
}
b := data[index]
index++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + int(stringLen)
if postIndex > l {
return io5.ErrUnexpectedEOF
}
s := string(data[index:postIndex])
m.ConnectionString = &s
index = postIndex
default:
var sizeOfWire int
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
index -= sizeOfWire
skippy, err := code_google_com_p_gogoprotobuf_proto10.Skip(data[index:])
if err != nil {
return err
}
if (index + skippy) > l {
return io5.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
index += skippy
}
}
return nil
}
func (this *SnapshotRecoveryRequest) String() string {
if this == nil {
return "nil"
}
s := strings10.Join([]string{`&SnapshotRecoveryRequest{`,
`LeaderName:` + valueToStringSnapshotRecoveryRequest(this.LeaderName) + `,`,
`LastIndex:` + valueToStringSnapshotRecoveryRequest(this.LastIndex) + `,`,
`LastTerm:` + valueToStringSnapshotRecoveryRequest(this.LastTerm) + `,`,
`Peers:` + strings10.Replace(fmt21.Sprintf("%v", this.Peers), "SnapshotRecoveryRequest_Peer", "SnapshotRecoveryRequest_Peer", 1) + `,`,
`State:` + valueToStringSnapshotRecoveryRequest(this.State) + `,`,
`XXX_unrecognized:` + fmt21.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func (this *SnapshotRecoveryRequest_Peer) String() string {
if this == nil {
return "nil"
}
s := strings10.Join([]string{`&SnapshotRecoveryRequest_Peer{`,
`Name:` + valueToStringSnapshotRecoveryRequest(this.Name) + `,`,
`ConnectionString:` + valueToStringSnapshotRecoveryRequest(this.ConnectionString) + `,`,
`XXX_unrecognized:` + fmt21.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringSnapshotRecoveryRequest(v interface{}) string {
rv := reflect10.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect10.Indirect(rv).Interface()
return fmt21.Sprintf("*%v", pv)
}
func (m *SnapshotRecoveryRequest) Size() (n int) {
var l int
_ = l
if m.LeaderName != nil {
l = len(*m.LeaderName)
n += 1 + l + sovSnapshotRecoveryRequest(uint64(l))
}
if m.LastIndex != nil {
n += 1 + sovSnapshotRecoveryRequest(uint64(*m.LastIndex))
}
if m.LastTerm != nil {
n += 1 + sovSnapshotRecoveryRequest(uint64(*m.LastTerm))
}
if len(m.Peers) > 0 {
for _, e := range m.Peers {
l = e.Size()
n += 1 + l + sovSnapshotRecoveryRequest(uint64(l))
}
}
if m.State != nil {
l = len(m.State)
n += 1 + l + sovSnapshotRecoveryRequest(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *SnapshotRecoveryRequest_Peer) Size() (n int) {
var l int
_ = l
if m.Name != nil {
l = len(*m.Name)
n += 1 + l + sovSnapshotRecoveryRequest(uint64(l))
}
if m.ConnectionString != nil {
l = len(*m.ConnectionString)
n += 1 + l + sovSnapshotRecoveryRequest(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovSnapshotRecoveryRequest(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozSnapshotRecoveryRequest(x uint64) (n int) {
return sovSnapshotRecoveryRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func NewPopulatedSnapshotRecoveryRequest(r randySnapshotRecoveryRequest, easy bool) *SnapshotRecoveryRequest {
this := &SnapshotRecoveryRequest{}
v1 := randStringSnapshotRecoveryRequest(r)
this.LeaderName = &v1
v2 := uint64(r.Uint32())
this.LastIndex = &v2
v3 := uint64(r.Uint32())
this.LastTerm = &v3
if r.Intn(10) != 0 {
v4 := r.Intn(10)
this.Peers = make([]*SnapshotRecoveryRequest_Peer, v4)
for i := 0; i < v4; i++ {
this.Peers[i] = NewPopulatedSnapshotRecoveryRequest_Peer(r, easy)
}
}
v5 := r.Intn(100)
this.State = make([]byte, v5)
for i := 0; i < v5; i++ {
this.State[i] = byte(r.Intn(256))
}
if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedSnapshotRecoveryRequest(r, 6)
}
return this
}
func NewPopulatedSnapshotRecoveryRequest_Peer(r randySnapshotRecoveryRequest, easy bool) *SnapshotRecoveryRequest_Peer {
this := &SnapshotRecoveryRequest_Peer{}
v6 := randStringSnapshotRecoveryRequest(r)
this.Name = &v6
v7 := randStringSnapshotRecoveryRequest(r)
this.ConnectionString = &v7
if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedSnapshotRecoveryRequest(r, 3)
}
return this
}
type randySnapshotRecoveryRequest interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneSnapshotRecoveryRequest(r randySnapshotRecoveryRequest) rune {
res := rune(r.Uint32() % 1112064)
if 55296 <= res {
res += 2047
}
return res
}
func randStringSnapshotRecoveryRequest(r randySnapshotRecoveryRequest) string {
v8 := r.Intn(100)
tmps := make([]rune, v8)
for i := 0; i < v8; i++ {
tmps[i] = randUTF8RuneSnapshotRecoveryRequest(r)
}
return string(tmps)
}
func randUnrecognizedSnapshotRecoveryRequest(r randySnapshotRecoveryRequest, maxFieldNumber int) (data []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
data = randFieldSnapshotRecoveryRequest(data, r, fieldNumber, wire)
}
return data
}
func randFieldSnapshotRecoveryRequest(data []byte, r randySnapshotRecoveryRequest, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(key))
v9 := r.Int63()
if r.Intn(2) == 0 {
v9 *= -1
}
data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(v9))
case 1:
data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(key))
ll := r.Intn(100)
data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(ll))
for j := 0; j < ll; j++ {
data = append(data, byte(r.Intn(256)))
}
default:
data = encodeVarintPopulateSnapshotRecoveryRequest(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return data
}
func encodeVarintPopulateSnapshotRecoveryRequest(data []byte, v uint64) []byte {
for v >= 1<<7 {
data = append(data, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
data = append(data, uint8(v))
return data
}
func (m *SnapshotRecoveryRequest) 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 *SnapshotRecoveryRequest) MarshalTo(data []byte) (n int, err error) {
var i int
_ = i
var l int
_ = l
if m.LeaderName != nil {
data[i] = 0xa
i++
i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(len(*m.LeaderName)))
i += copy(data[i:], *m.LeaderName)
}
if m.LastIndex != nil {
data[i] = 0x10
i++
i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(*m.LastIndex))
}
if m.LastTerm != nil {
data[i] = 0x18
i++
i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(*m.LastTerm))
}
if len(m.Peers) > 0 {
for _, msg := range m.Peers {
data[i] = 0x22
i++
i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(msg.Size()))
n, err := msg.MarshalTo(data[i:])
if err != nil {
return 0, err
}
i += n
}
}
if m.State != nil {
data[i] = 0x2a
i++
i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(len(m.State)))
i += copy(data[i:], m.State)
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func (m *SnapshotRecoveryRequest_Peer) 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 *SnapshotRecoveryRequest_Peer) MarshalTo(data []byte) (n int, err error) {
var i int
_ = i
var l int
_ = l
if m.Name != nil {
data[i] = 0xa
i++
i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(len(*m.Name)))
i += copy(data[i:], *m.Name)
}
if m.ConnectionString != nil {
data[i] = 0x12
i++
i = encodeVarintSnapshotRecoveryRequest(data, i, uint64(len(*m.ConnectionString)))
i += copy(data[i:], *m.ConnectionString)
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeFixed64SnapshotRecoveryRequest(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
data[offset+4] = uint8(v >> 32)
data[offset+5] = uint8(v >> 40)
data[offset+6] = uint8(v >> 48)
data[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32SnapshotRecoveryRequest(data []byte, offset int, v uint32) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintSnapshotRecoveryRequest(data []byte, offset int, v uint64) int {
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
}
func (this *SnapshotRecoveryRequest) GoString() string {
if this == nil {
return "nil"
}
s := strings11.Join([]string{`&protobuf.SnapshotRecoveryRequest{` + `LeaderName:` + valueToGoStringSnapshotRecoveryRequest(this.LeaderName, "string"), `LastIndex:` + valueToGoStringSnapshotRecoveryRequest(this.LastIndex, "uint64"), `LastTerm:` + valueToGoStringSnapshotRecoveryRequest(this.LastTerm, "uint64"), `Peers:` + fmt22.Sprintf("%#v", this.Peers), `State:` + valueToGoStringSnapshotRecoveryRequest(this.State, "byte"), `XXX_unrecognized:` + fmt22.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
return s
}
func (this *SnapshotRecoveryRequest_Peer) GoString() string {
if this == nil {
return "nil"
}
s := strings11.Join([]string{`&protobuf.SnapshotRecoveryRequest_Peer{` + `Name:` + valueToGoStringSnapshotRecoveryRequest(this.Name, "string"), `ConnectionString:` + valueToGoStringSnapshotRecoveryRequest(this.ConnectionString, "string"), `XXX_unrecognized:` + fmt22.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
return s
}
func valueToGoStringSnapshotRecoveryRequest(v interface{}, typ string) string {
rv := reflect11.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect11.Indirect(rv).Interface()
return fmt22.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringSnapshotRecoveryRequest(e map[int32]code_google_com_p_gogoprotobuf_proto11.Extension) string {
if e == nil {
return "nil"
}
s := "map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort5.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv5.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings11.Join(ss, ",") + "}"
return s
}
func (this *SnapshotRecoveryRequest) VerboseEqual(that interface{}) error {
if that == nil {
if this == nil {
return nil
}
return fmt23.Errorf("that == nil && this != nil")
}
that1, ok := that.(*SnapshotRecoveryRequest)
if !ok {
return fmt23.Errorf("that is not of type *SnapshotRecoveryRequest")
}
if that1 == nil {
if this == nil {
return nil
}
return fmt23.Errorf("that is type *SnapshotRecoveryRequest but is nil && this != nil")
} else if this == nil {
return fmt23.Errorf("that is type *SnapshotRecoveryRequestbut is not nil && this == nil")
}
if this.LeaderName != nil && that1.LeaderName != nil {
if *this.LeaderName != *that1.LeaderName {
return fmt23.Errorf("LeaderName this(%v) Not Equal that(%v)", *this.LeaderName, *that1.LeaderName)
}
} else if this.LeaderName != nil {
return fmt23.Errorf("this.LeaderName == nil && that.LeaderName != nil")
} else if that1.LeaderName != nil {
return fmt23.Errorf("LeaderName this(%v) Not Equal that(%v)", this.LeaderName, that1.LeaderName)
}
if this.LastIndex != nil && that1.LastIndex != nil {
if *this.LastIndex != *that1.LastIndex {
return fmt23.Errorf("LastIndex this(%v) Not Equal that(%v)", *this.LastIndex, *that1.LastIndex)
}
} else if this.LastIndex != nil {
return fmt23.Errorf("this.LastIndex == nil && that.LastIndex != nil")
} else if that1.LastIndex != nil {
return fmt23.Errorf("LastIndex this(%v) Not Equal that(%v)", this.LastIndex, that1.LastIndex)
}
if this.LastTerm != nil && that1.LastTerm != nil {
if *this.LastTerm != *that1.LastTerm {
return fmt23.Errorf("LastTerm this(%v) Not Equal that(%v)", *this.LastTerm, *that1.LastTerm)
}
} else if this.LastTerm != nil {
return fmt23.Errorf("this.LastTerm == nil && that.LastTerm != nil")
} else if that1.LastTerm != nil {
return fmt23.Errorf("LastTerm this(%v) Not Equal that(%v)", this.LastTerm, that1.LastTerm)
}
if len(this.Peers) != len(that1.Peers) {
return fmt23.Errorf("Peers this(%v) Not Equal that(%v)", len(this.Peers), len(that1.Peers))
}
for i := range this.Peers {
if !this.Peers[i].Equal(that1.Peers[i]) {
return fmt23.Errorf("Peers this[%v](%v) Not Equal that[%v](%v)", i, this.Peers[i], i, that1.Peers[i])
}
}
if !bytes5.Equal(this.State, that1.State) {
return fmt23.Errorf("State this(%v) Not Equal that(%v)", this.State, that1.State)
}
if !bytes5.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return fmt23.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
}
return nil
}
func (this *SnapshotRecoveryRequest) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*SnapshotRecoveryRequest)
if !ok {
return false
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.LeaderName != nil && that1.LeaderName != nil {
if *this.LeaderName != *that1.LeaderName {
return false
}
} else if this.LeaderName != nil {
return false
} else if that1.LeaderName != nil {
return false
}
if this.LastIndex != nil && that1.LastIndex != nil {
if *this.LastIndex != *that1.LastIndex {
return false
}
} else if this.LastIndex != nil {
return false
} else if that1.LastIndex != nil {
return false
}
if this.LastTerm != nil && that1.LastTerm != nil {
if *this.LastTerm != *that1.LastTerm {
return false
}
} else if this.LastTerm != nil {
return false
} else if that1.LastTerm != nil {
return false
}
if len(this.Peers) != len(that1.Peers) {
return false
}
for i := range this.Peers {
if !this.Peers[i].Equal(that1.Peers[i]) {
return false
}
}
if !bytes5.Equal(this.State, that1.State) {
return false
}
if !bytes5.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false
}
return true
}
func (this *SnapshotRecoveryRequest_Peer) VerboseEqual(that interface{}) error {
if that == nil {
if this == nil {
return nil
}
return fmt23.Errorf("that == nil && this != nil")
}
that1, ok := that.(*SnapshotRecoveryRequest_Peer)
if !ok {
return fmt23.Errorf("that is not of type *SnapshotRecoveryRequest_Peer")
}
if that1 == nil {
if this == nil {
return nil
}
return fmt23.Errorf("that is type *SnapshotRecoveryRequest_Peer but is nil && this != nil")
} else if this == nil {
return fmt23.Errorf("that is type *SnapshotRecoveryRequest_Peerbut is not nil && this == nil")
}
if this.Name != nil && that1.Name != nil {
if *this.Name != *that1.Name {
return fmt23.Errorf("Name this(%v) Not Equal that(%v)", *this.Name, *that1.Name)
}
} else if this.Name != nil {
return fmt23.Errorf("this.Name == nil && that.Name != nil")
} else if that1.Name != nil {
return fmt23.Errorf("Name this(%v) Not Equal that(%v)", this.Name, that1.Name)
}
if this.ConnectionString != nil && that1.ConnectionString != nil {
if *this.ConnectionString != *that1.ConnectionString {
return fmt23.Errorf("ConnectionString this(%v) Not Equal that(%v)", *this.ConnectionString, *that1.ConnectionString)
}
} else if this.ConnectionString != nil {
return fmt23.Errorf("this.ConnectionString == nil && that.ConnectionString != nil")
} else if that1.ConnectionString != nil {
return fmt23.Errorf("ConnectionString this(%v) Not Equal that(%v)", this.ConnectionString, that1.ConnectionString)
}
if !bytes5.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return fmt23.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
}
return nil
}
func (this *SnapshotRecoveryRequest_Peer) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*SnapshotRecoveryRequest_Peer)
if !ok {
return false
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.Name != nil && that1.Name != nil {
if *this.Name != *that1.Name {
return false
}
} else if this.Name != nil {
return false
} else if that1.Name != nil {
return false
}
if this.ConnectionString != nil && that1.ConnectionString != nil {
if *this.ConnectionString != *that1.ConnectionString {
return false
}
} else if this.ConnectionString != nil {
return false
} else if that1.ConnectionString != nil {
return false
}
if !bytes5.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false
}
return true
}

View File

@ -1,29 +0,0 @@
package protobuf;
import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message SnapshotRecoveryRequest {
required string LeaderName=1;
required uint64 LastIndex=2;
required uint64 LastTerm=3;
message Peer {
required string Name=1;
required string ConnectionString=2;
}
repeated Peer Peers=4;
required bytes State=5;
}

View File

@ -1,499 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: snapshot_recovery_response.proto
// DO NOT EDIT!
package protobuf
import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"
// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
import io6 "io"
import fmt24 "fmt"
import code_google_com_p_gogoprotobuf_proto12 "code.google.com/p/gogoprotobuf/proto"
import fmt25 "fmt"
import strings12 "strings"
import reflect12 "reflect"
import fmt26 "fmt"
import strings13 "strings"
import code_google_com_p_gogoprotobuf_proto13 "code.google.com/p/gogoprotobuf/proto"
import sort6 "sort"
import strconv6 "strconv"
import reflect13 "reflect"
import fmt27 "fmt"
import bytes6 "bytes"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type SnapshotRecoveryResponse struct {
Term *uint64 `protobuf:"varint,1,req" json:"Term,omitempty"`
Success *bool `protobuf:"varint,2,req" json:"Success,omitempty"`
CommitIndex *uint64 `protobuf:"varint,3,req" json:"CommitIndex,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotRecoveryResponse) Reset() { *m = SnapshotRecoveryResponse{} }
func (*SnapshotRecoveryResponse) ProtoMessage() {}
func (m *SnapshotRecoveryResponse) GetTerm() uint64 {
if m != nil && m.Term != nil {
return *m.Term
}
return 0
}
func (m *SnapshotRecoveryResponse) GetSuccess() bool {
if m != nil && m.Success != nil {
return *m.Success
}
return false
}
func (m *SnapshotRecoveryResponse) GetCommitIndex() uint64 {
if m != nil && m.CommitIndex != nil {
return *m.CommitIndex
}
return 0
}
func init() {
}
func (m *SnapshotRecoveryResponse) Unmarshal(data []byte) error {
l := len(data)
index := 0
for index < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io6.ErrUnexpectedEOF
}
b := data[index]
index++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
switch fieldNum {
case 1:
if wireType != 0 {
return fmt24.Errorf("proto: wrong wireType = %d for field Term", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io6.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Term = &v
case 2:
if wireType != 0 {
return fmt24.Errorf("proto: wrong wireType = %d for field Success", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if index >= l {
return io6.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
b := bool(v != 0)
m.Success = &b
case 3:
if wireType != 0 {
return fmt24.Errorf("proto: wrong wireType = %d for field CommitIndex", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io6.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.CommitIndex = &v
default:
var sizeOfWire int
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
index -= sizeOfWire
skippy, err := code_google_com_p_gogoprotobuf_proto12.Skip(data[index:])
if err != nil {
return err
}
if (index + skippy) > l {
return io6.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
index += skippy
}
}
return nil
}
func (this *SnapshotRecoveryResponse) String() string {
if this == nil {
return "nil"
}
s := strings12.Join([]string{`&SnapshotRecoveryResponse{`,
`Term:` + valueToStringSnapshotRecoveryResponse(this.Term) + `,`,
`Success:` + valueToStringSnapshotRecoveryResponse(this.Success) + `,`,
`CommitIndex:` + valueToStringSnapshotRecoveryResponse(this.CommitIndex) + `,`,
`XXX_unrecognized:` + fmt25.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringSnapshotRecoveryResponse(v interface{}) string {
rv := reflect12.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect12.Indirect(rv).Interface()
return fmt25.Sprintf("*%v", pv)
}
func (m *SnapshotRecoveryResponse) Size() (n int) {
var l int
_ = l
if m.Term != nil {
n += 1 + sovSnapshotRecoveryResponse(uint64(*m.Term))
}
if m.Success != nil {
n += 2
}
if m.CommitIndex != nil {
n += 1 + sovSnapshotRecoveryResponse(uint64(*m.CommitIndex))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovSnapshotRecoveryResponse(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozSnapshotRecoveryResponse(x uint64) (n int) {
return sovSnapshotRecoveryResponse(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func NewPopulatedSnapshotRecoveryResponse(r randySnapshotRecoveryResponse, easy bool) *SnapshotRecoveryResponse {
this := &SnapshotRecoveryResponse{}
v1 := uint64(r.Uint32())
this.Term = &v1
v2 := bool(r.Intn(2) == 0)
this.Success = &v2
v3 := uint64(r.Uint32())
this.CommitIndex = &v3
if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedSnapshotRecoveryResponse(r, 4)
}
return this
}
type randySnapshotRecoveryResponse interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneSnapshotRecoveryResponse(r randySnapshotRecoveryResponse) rune {
res := rune(r.Uint32() % 1112064)
if 55296 <= res {
res += 2047
}
return res
}
func randStringSnapshotRecoveryResponse(r randySnapshotRecoveryResponse) string {
v4 := r.Intn(100)
tmps := make([]rune, v4)
for i := 0; i < v4; i++ {
tmps[i] = randUTF8RuneSnapshotRecoveryResponse(r)
}
return string(tmps)
}
func randUnrecognizedSnapshotRecoveryResponse(r randySnapshotRecoveryResponse, maxFieldNumber int) (data []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
data = randFieldSnapshotRecoveryResponse(data, r, fieldNumber, wire)
}
return data
}
func randFieldSnapshotRecoveryResponse(data []byte, r randySnapshotRecoveryResponse, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(key))
v5 := r.Int63()
if r.Intn(2) == 0 {
v5 *= -1
}
data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(v5))
case 1:
data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(key))
ll := r.Intn(100)
data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(ll))
for j := 0; j < ll; j++ {
data = append(data, byte(r.Intn(256)))
}
default:
data = encodeVarintPopulateSnapshotRecoveryResponse(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return data
}
func encodeVarintPopulateSnapshotRecoveryResponse(data []byte, v uint64) []byte {
for v >= 1<<7 {
data = append(data, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
data = append(data, uint8(v))
return data
}
func (m *SnapshotRecoveryResponse) 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 *SnapshotRecoveryResponse) MarshalTo(data []byte) (n int, err error) {
var i int
_ = i
var l int
_ = l
if m.Term != nil {
data[i] = 0x8
i++
i = encodeVarintSnapshotRecoveryResponse(data, i, uint64(*m.Term))
}
if m.Success != nil {
data[i] = 0x10
i++
if *m.Success {
data[i] = 1
} else {
data[i] = 0
}
i++
}
if m.CommitIndex != nil {
data[i] = 0x18
i++
i = encodeVarintSnapshotRecoveryResponse(data, i, uint64(*m.CommitIndex))
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeFixed64SnapshotRecoveryResponse(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
data[offset+4] = uint8(v >> 32)
data[offset+5] = uint8(v >> 40)
data[offset+6] = uint8(v >> 48)
data[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32SnapshotRecoveryResponse(data []byte, offset int, v uint32) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintSnapshotRecoveryResponse(data []byte, offset int, v uint64) int {
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
}
func (this *SnapshotRecoveryResponse) GoString() string {
if this == nil {
return "nil"
}
s := strings13.Join([]string{`&protobuf.SnapshotRecoveryResponse{` + `Term:` + valueToGoStringSnapshotRecoveryResponse(this.Term, "uint64"), `Success:` + valueToGoStringSnapshotRecoveryResponse(this.Success, "bool"), `CommitIndex:` + valueToGoStringSnapshotRecoveryResponse(this.CommitIndex, "uint64"), `XXX_unrecognized:` + fmt26.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
return s
}
func valueToGoStringSnapshotRecoveryResponse(v interface{}, typ string) string {
rv := reflect13.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect13.Indirect(rv).Interface()
return fmt26.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringSnapshotRecoveryResponse(e map[int32]code_google_com_p_gogoprotobuf_proto13.Extension) string {
if e == nil {
return "nil"
}
s := "map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort6.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv6.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings13.Join(ss, ",") + "}"
return s
}
func (this *SnapshotRecoveryResponse) VerboseEqual(that interface{}) error {
if that == nil {
if this == nil {
return nil
}
return fmt27.Errorf("that == nil && this != nil")
}
that1, ok := that.(*SnapshotRecoveryResponse)
if !ok {
return fmt27.Errorf("that is not of type *SnapshotRecoveryResponse")
}
if that1 == nil {
if this == nil {
return nil
}
return fmt27.Errorf("that is type *SnapshotRecoveryResponse but is nil && this != nil")
} else if this == nil {
return fmt27.Errorf("that is type *SnapshotRecoveryResponsebut is not nil && this == nil")
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return fmt27.Errorf("Term this(%v) Not Equal that(%v)", *this.Term, *that1.Term)
}
} else if this.Term != nil {
return fmt27.Errorf("this.Term == nil && that.Term != nil")
} else if that1.Term != nil {
return fmt27.Errorf("Term this(%v) Not Equal that(%v)", this.Term, that1.Term)
}
if this.Success != nil && that1.Success != nil {
if *this.Success != *that1.Success {
return fmt27.Errorf("Success this(%v) Not Equal that(%v)", *this.Success, *that1.Success)
}
} else if this.Success != nil {
return fmt27.Errorf("this.Success == nil && that.Success != nil")
} else if that1.Success != nil {
return fmt27.Errorf("Success this(%v) Not Equal that(%v)", this.Success, that1.Success)
}
if this.CommitIndex != nil && that1.CommitIndex != nil {
if *this.CommitIndex != *that1.CommitIndex {
return fmt27.Errorf("CommitIndex this(%v) Not Equal that(%v)", *this.CommitIndex, *that1.CommitIndex)
}
} else if this.CommitIndex != nil {
return fmt27.Errorf("this.CommitIndex == nil && that.CommitIndex != nil")
} else if that1.CommitIndex != nil {
return fmt27.Errorf("CommitIndex this(%v) Not Equal that(%v)", this.CommitIndex, that1.CommitIndex)
}
if !bytes6.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return fmt27.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
}
return nil
}
func (this *SnapshotRecoveryResponse) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*SnapshotRecoveryResponse)
if !ok {
return false
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.Term != nil && that1.Term != nil {
if *this.Term != *that1.Term {
return false
}
} else if this.Term != nil {
return false
} else if that1.Term != nil {
return false
}
if this.Success != nil && that1.Success != nil {
if *this.Success != *that1.Success {
return false
}
} else if this.Success != nil {
return false
} else if that1.Success != nil {
return false
}
if this.CommitIndex != nil && that1.CommitIndex != nil {
if *this.CommitIndex != *that1.CommitIndex {
return false
}
} else if this.CommitIndex != nil {
return false
} else if that1.CommitIndex != nil {
return false
}
if !bytes6.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false
}
return true
}

View File

@ -1,21 +0,0 @@
package protobuf;
import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message SnapshotRecoveryResponse {
required uint64 Term=1;
required bool Success=2;
required uint64 CommitIndex=3;
}

View File

@ -1,501 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: snapshot_request.proto
// DO NOT EDIT!
package protobuf
import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"
// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
import io7 "io"
import fmt28 "fmt"
import code_google_com_p_gogoprotobuf_proto14 "code.google.com/p/gogoprotobuf/proto"
import fmt29 "fmt"
import strings14 "strings"
import reflect14 "reflect"
import fmt30 "fmt"
import strings15 "strings"
import code_google_com_p_gogoprotobuf_proto15 "code.google.com/p/gogoprotobuf/proto"
import sort7 "sort"
import strconv7 "strconv"
import reflect15 "reflect"
import fmt31 "fmt"
import bytes7 "bytes"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type SnapshotRequest struct {
LeaderName *string `protobuf:"bytes,1,req" json:"LeaderName,omitempty"`
LastIndex *uint64 `protobuf:"varint,2,req" json:"LastIndex,omitempty"`
LastTerm *uint64 `protobuf:"varint,3,req" json:"LastTerm,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotRequest) Reset() { *m = SnapshotRequest{} }
func (*SnapshotRequest) ProtoMessage() {}
func (m *SnapshotRequest) GetLeaderName() string {
if m != nil && m.LeaderName != nil {
return *m.LeaderName
}
return ""
}
func (m *SnapshotRequest) GetLastIndex() uint64 {
if m != nil && m.LastIndex != nil {
return *m.LastIndex
}
return 0
}
func (m *SnapshotRequest) GetLastTerm() uint64 {
if m != nil && m.LastTerm != nil {
return *m.LastTerm
}
return 0
}
func init() {
}
func (m *SnapshotRequest) Unmarshal(data []byte) error {
l := len(data)
index := 0
for index < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io7.ErrUnexpectedEOF
}
b := data[index]
index++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
switch fieldNum {
case 1:
if wireType != 2 {
return fmt28.Errorf("proto: wrong wireType = %d for field LeaderName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io7.ErrUnexpectedEOF
}
b := data[index]
index++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
postIndex := index + int(stringLen)
if postIndex > l {
return io7.ErrUnexpectedEOF
}
s := string(data[index:postIndex])
m.LeaderName = &s
index = postIndex
case 2:
if wireType != 0 {
return fmt28.Errorf("proto: wrong wireType = %d for field LastIndex", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io7.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.LastIndex = &v
case 3:
if wireType != 0 {
return fmt28.Errorf("proto: wrong wireType = %d for field LastTerm", wireType)
}
var v uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io7.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.LastTerm = &v
default:
var sizeOfWire int
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
index -= sizeOfWire
skippy, err := code_google_com_p_gogoprotobuf_proto14.Skip(data[index:])
if err != nil {
return err
}
if (index + skippy) > l {
return io7.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
index += skippy
}
}
return nil
}
func (this *SnapshotRequest) String() string {
if this == nil {
return "nil"
}
s := strings14.Join([]string{`&SnapshotRequest{`,
`LeaderName:` + valueToStringSnapshotRequest(this.LeaderName) + `,`,
`LastIndex:` + valueToStringSnapshotRequest(this.LastIndex) + `,`,
`LastTerm:` + valueToStringSnapshotRequest(this.LastTerm) + `,`,
`XXX_unrecognized:` + fmt29.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringSnapshotRequest(v interface{}) string {
rv := reflect14.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect14.Indirect(rv).Interface()
return fmt29.Sprintf("*%v", pv)
}
func (m *SnapshotRequest) Size() (n int) {
var l int
_ = l
if m.LeaderName != nil {
l = len(*m.LeaderName)
n += 1 + l + sovSnapshotRequest(uint64(l))
}
if m.LastIndex != nil {
n += 1 + sovSnapshotRequest(uint64(*m.LastIndex))
}
if m.LastTerm != nil {
n += 1 + sovSnapshotRequest(uint64(*m.LastTerm))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovSnapshotRequest(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozSnapshotRequest(x uint64) (n int) {
return sovSnapshotRequest(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func NewPopulatedSnapshotRequest(r randySnapshotRequest, easy bool) *SnapshotRequest {
this := &SnapshotRequest{}
v1 := randStringSnapshotRequest(r)
this.LeaderName = &v1
v2 := uint64(r.Uint32())
this.LastIndex = &v2
v3 := uint64(r.Uint32())
this.LastTerm = &v3
if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedSnapshotRequest(r, 4)
}
return this
}
type randySnapshotRequest interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneSnapshotRequest(r randySnapshotRequest) rune {
res := rune(r.Uint32() % 1112064)
if 55296 <= res {
res += 2047
}
return res
}
func randStringSnapshotRequest(r randySnapshotRequest) string {
v4 := r.Intn(100)
tmps := make([]rune, v4)
for i := 0; i < v4; i++ {
tmps[i] = randUTF8RuneSnapshotRequest(r)
}
return string(tmps)
}
func randUnrecognizedSnapshotRequest(r randySnapshotRequest, maxFieldNumber int) (data []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
data = randFieldSnapshotRequest(data, r, fieldNumber, wire)
}
return data
}
func randFieldSnapshotRequest(data []byte, r randySnapshotRequest, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
data = encodeVarintPopulateSnapshotRequest(data, uint64(key))
v5 := r.Int63()
if r.Intn(2) == 0 {
v5 *= -1
}
data = encodeVarintPopulateSnapshotRequest(data, uint64(v5))
case 1:
data = encodeVarintPopulateSnapshotRequest(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
data = encodeVarintPopulateSnapshotRequest(data, uint64(key))
ll := r.Intn(100)
data = encodeVarintPopulateSnapshotRequest(data, uint64(ll))
for j := 0; j < ll; j++ {
data = append(data, byte(r.Intn(256)))
}
default:
data = encodeVarintPopulateSnapshotRequest(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return data
}
func encodeVarintPopulateSnapshotRequest(data []byte, v uint64) []byte {
for v >= 1<<7 {
data = append(data, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
data = append(data, uint8(v))
return data
}
func (m *SnapshotRequest) 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 *SnapshotRequest) MarshalTo(data []byte) (n int, err error) {
var i int
_ = i
var l int
_ = l
if m.LeaderName != nil {
data[i] = 0xa
i++
i = encodeVarintSnapshotRequest(data, i, uint64(len(*m.LeaderName)))
i += copy(data[i:], *m.LeaderName)
}
if m.LastIndex != nil {
data[i] = 0x10
i++
i = encodeVarintSnapshotRequest(data, i, uint64(*m.LastIndex))
}
if m.LastTerm != nil {
data[i] = 0x18
i++
i = encodeVarintSnapshotRequest(data, i, uint64(*m.LastTerm))
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeFixed64SnapshotRequest(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
data[offset+4] = uint8(v >> 32)
data[offset+5] = uint8(v >> 40)
data[offset+6] = uint8(v >> 48)
data[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32SnapshotRequest(data []byte, offset int, v uint32) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintSnapshotRequest(data []byte, offset int, v uint64) int {
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
}
func (this *SnapshotRequest) GoString() string {
if this == nil {
return "nil"
}
s := strings15.Join([]string{`&protobuf.SnapshotRequest{` + `LeaderName:` + valueToGoStringSnapshotRequest(this.LeaderName, "string"), `LastIndex:` + valueToGoStringSnapshotRequest(this.LastIndex, "uint64"), `LastTerm:` + valueToGoStringSnapshotRequest(this.LastTerm, "uint64"), `XXX_unrecognized:` + fmt30.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
return s
}
func valueToGoStringSnapshotRequest(v interface{}, typ string) string {
rv := reflect15.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect15.Indirect(rv).Interface()
return fmt30.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringSnapshotRequest(e map[int32]code_google_com_p_gogoprotobuf_proto15.Extension) string {
if e == nil {
return "nil"
}
s := "map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort7.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv7.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings15.Join(ss, ",") + "}"
return s
}
func (this *SnapshotRequest) VerboseEqual(that interface{}) error {
if that == nil {
if this == nil {
return nil
}
return fmt31.Errorf("that == nil && this != nil")
}
that1, ok := that.(*SnapshotRequest)
if !ok {
return fmt31.Errorf("that is not of type *SnapshotRequest")
}
if that1 == nil {
if this == nil {
return nil
}
return fmt31.Errorf("that is type *SnapshotRequest but is nil && this != nil")
} else if this == nil {
return fmt31.Errorf("that is type *SnapshotRequestbut is not nil && this == nil")
}
if this.LeaderName != nil && that1.LeaderName != nil {
if *this.LeaderName != *that1.LeaderName {
return fmt31.Errorf("LeaderName this(%v) Not Equal that(%v)", *this.LeaderName, *that1.LeaderName)
}
} else if this.LeaderName != nil {
return fmt31.Errorf("this.LeaderName == nil && that.LeaderName != nil")
} else if that1.LeaderName != nil {
return fmt31.Errorf("LeaderName this(%v) Not Equal that(%v)", this.LeaderName, that1.LeaderName)
}
if this.LastIndex != nil && that1.LastIndex != nil {
if *this.LastIndex != *that1.LastIndex {
return fmt31.Errorf("LastIndex this(%v) Not Equal that(%v)", *this.LastIndex, *that1.LastIndex)
}
} else if this.LastIndex != nil {
return fmt31.Errorf("this.LastIndex == nil && that.LastIndex != nil")
} else if that1.LastIndex != nil {
return fmt31.Errorf("LastIndex this(%v) Not Equal that(%v)", this.LastIndex, that1.LastIndex)
}
if this.LastTerm != nil && that1.LastTerm != nil {
if *this.LastTerm != *that1.LastTerm {
return fmt31.Errorf("LastTerm this(%v) Not Equal that(%v)", *this.LastTerm, *that1.LastTerm)
}
} else if this.LastTerm != nil {
return fmt31.Errorf("this.LastTerm == nil && that.LastTerm != nil")
} else if that1.LastTerm != nil {
return fmt31.Errorf("LastTerm this(%v) Not Equal that(%v)", this.LastTerm, that1.LastTerm)
}
if !bytes7.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return fmt31.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
}
return nil
}
func (this *SnapshotRequest) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*SnapshotRequest)
if !ok {
return false
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.LeaderName != nil && that1.LeaderName != nil {
if *this.LeaderName != *that1.LeaderName {
return false
}
} else if this.LeaderName != nil {
return false
} else if that1.LeaderName != nil {
return false
}
if this.LastIndex != nil && that1.LastIndex != nil {
if *this.LastIndex != *that1.LastIndex {
return false
}
} else if this.LastIndex != nil {
return false
} else if that1.LastIndex != nil {
return false
}
if this.LastTerm != nil && that1.LastTerm != nil {
if *this.LastTerm != *that1.LastTerm {
return false
}
} else if this.LastTerm != nil {
return false
} else if that1.LastTerm != nil {
return false
}
if !bytes7.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false
}
return true
}

View File

@ -1,21 +0,0 @@
package protobuf;
import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message SnapshotRequest {
required string LeaderName=1;
required uint64 LastIndex=2;
required uint64 LastTerm=3;
}

View File

@ -1,391 +0,0 @@
// Code generated by protoc-gen-gogo.
// source: snapshot_response.proto
// DO NOT EDIT!
package protobuf
import proto "code.google.com/p/gogoprotobuf/proto"
import math "math"
// discarding unused import gogoproto "code.google.com/p/gogoprotobuf/gogoproto/gogo.pb"
import io8 "io"
import fmt32 "fmt"
import code_google_com_p_gogoprotobuf_proto16 "code.google.com/p/gogoprotobuf/proto"
import fmt33 "fmt"
import strings16 "strings"
import reflect16 "reflect"
import fmt34 "fmt"
import strings17 "strings"
import code_google_com_p_gogoprotobuf_proto17 "code.google.com/p/gogoprotobuf/proto"
import sort8 "sort"
import strconv8 "strconv"
import reflect17 "reflect"
import fmt35 "fmt"
import bytes8 "bytes"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = math.Inf
type SnapshotResponse struct {
Success *bool `protobuf:"varint,1,req" json:"Success,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotResponse) Reset() { *m = SnapshotResponse{} }
func (*SnapshotResponse) ProtoMessage() {}
func (m *SnapshotResponse) GetSuccess() bool {
if m != nil && m.Success != nil {
return *m.Success
}
return false
}
func init() {
}
func (m *SnapshotResponse) Unmarshal(data []byte) error {
l := len(data)
index := 0
for index < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if index >= l {
return io8.ErrUnexpectedEOF
}
b := data[index]
index++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
switch fieldNum {
case 1:
if wireType != 0 {
return fmt32.Errorf("proto: wrong wireType = %d for field Success", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if index >= l {
return io8.ErrUnexpectedEOF
}
b := data[index]
index++
v |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
b := bool(v != 0)
m.Success = &b
default:
var sizeOfWire int
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
index -= sizeOfWire
skippy, err := code_google_com_p_gogoprotobuf_proto16.Skip(data[index:])
if err != nil {
return err
}
if (index + skippy) > l {
return io8.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[index:index+skippy]...)
index += skippy
}
}
return nil
}
func (this *SnapshotResponse) String() string {
if this == nil {
return "nil"
}
s := strings16.Join([]string{`&SnapshotResponse{`,
`Success:` + valueToStringSnapshotResponse(this.Success) + `,`,
`XXX_unrecognized:` + fmt33.Sprintf("%v", this.XXX_unrecognized) + `,`,
`}`,
}, "")
return s
}
func valueToStringSnapshotResponse(v interface{}) string {
rv := reflect16.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect16.Indirect(rv).Interface()
return fmt33.Sprintf("*%v", pv)
}
func (m *SnapshotResponse) Size() (n int) {
var l int
_ = l
if m.Success != nil {
n += 2
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovSnapshotResponse(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozSnapshotResponse(x uint64) (n int) {
return sovSnapshotResponse(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func NewPopulatedSnapshotResponse(r randySnapshotResponse, easy bool) *SnapshotResponse {
this := &SnapshotResponse{}
v1 := bool(r.Intn(2) == 0)
this.Success = &v1
if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedSnapshotResponse(r, 2)
}
return this
}
type randySnapshotResponse interface {
Float32() float32
Float64() float64
Int63() int64
Int31() int32
Uint32() uint32
Intn(n int) int
}
func randUTF8RuneSnapshotResponse(r randySnapshotResponse) rune {
res := rune(r.Uint32() % 1112064)
if 55296 <= res {
res += 2047
}
return res
}
func randStringSnapshotResponse(r randySnapshotResponse) string {
v2 := r.Intn(100)
tmps := make([]rune, v2)
for i := 0; i < v2; i++ {
tmps[i] = randUTF8RuneSnapshotResponse(r)
}
return string(tmps)
}
func randUnrecognizedSnapshotResponse(r randySnapshotResponse, maxFieldNumber int) (data []byte) {
l := r.Intn(5)
for i := 0; i < l; i++ {
wire := r.Intn(4)
if wire == 3 {
wire = 5
}
fieldNumber := maxFieldNumber + r.Intn(100)
data = randFieldSnapshotResponse(data, r, fieldNumber, wire)
}
return data
}
func randFieldSnapshotResponse(data []byte, r randySnapshotResponse, fieldNumber int, wire int) []byte {
key := uint32(fieldNumber)<<3 | uint32(wire)
switch wire {
case 0:
data = encodeVarintPopulateSnapshotResponse(data, uint64(key))
v3 := r.Int63()
if r.Intn(2) == 0 {
v3 *= -1
}
data = encodeVarintPopulateSnapshotResponse(data, uint64(v3))
case 1:
data = encodeVarintPopulateSnapshotResponse(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
case 2:
data = encodeVarintPopulateSnapshotResponse(data, uint64(key))
ll := r.Intn(100)
data = encodeVarintPopulateSnapshotResponse(data, uint64(ll))
for j := 0; j < ll; j++ {
data = append(data, byte(r.Intn(256)))
}
default:
data = encodeVarintPopulateSnapshotResponse(data, uint64(key))
data = append(data, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))
}
return data
}
func encodeVarintPopulateSnapshotResponse(data []byte, v uint64) []byte {
for v >= 1<<7 {
data = append(data, uint8(uint64(v)&0x7f|0x80))
v >>= 7
}
data = append(data, uint8(v))
return data
}
func (m *SnapshotResponse) 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 *SnapshotResponse) MarshalTo(data []byte) (n int, err error) {
var i int
_ = i
var l int
_ = l
if m.Success != nil {
data[i] = 0x8
i++
if *m.Success {
data[i] = 1
} else {
data[i] = 0
}
i++
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeFixed64SnapshotResponse(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
data[offset+4] = uint8(v >> 32)
data[offset+5] = uint8(v >> 40)
data[offset+6] = uint8(v >> 48)
data[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32SnapshotResponse(data []byte, offset int, v uint32) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintSnapshotResponse(data []byte, offset int, v uint64) int {
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
}
func (this *SnapshotResponse) GoString() string {
if this == nil {
return "nil"
}
s := strings17.Join([]string{`&protobuf.SnapshotResponse{` + `Success:` + valueToGoStringSnapshotResponse(this.Success, "bool"), `XXX_unrecognized:` + fmt34.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
return s
}
func valueToGoStringSnapshotResponse(v interface{}, typ string) string {
rv := reflect17.ValueOf(v)
if rv.IsNil() {
return "nil"
}
pv := reflect17.Indirect(rv).Interface()
return fmt34.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)
}
func extensionToGoStringSnapshotResponse(e map[int32]code_google_com_p_gogoprotobuf_proto17.Extension) string {
if e == nil {
return "nil"
}
s := "map[int32]proto.Extension{"
keys := make([]int, 0, len(e))
for k := range e {
keys = append(keys, int(k))
}
sort8.Ints(keys)
ss := []string{}
for _, k := range keys {
ss = append(ss, strconv8.Itoa(k)+": "+e[int32(k)].GoString())
}
s += strings17.Join(ss, ",") + "}"
return s
}
func (this *SnapshotResponse) VerboseEqual(that interface{}) error {
if that == nil {
if this == nil {
return nil
}
return fmt35.Errorf("that == nil && this != nil")
}
that1, ok := that.(*SnapshotResponse)
if !ok {
return fmt35.Errorf("that is not of type *SnapshotResponse")
}
if that1 == nil {
if this == nil {
return nil
}
return fmt35.Errorf("that is type *SnapshotResponse but is nil && this != nil")
} else if this == nil {
return fmt35.Errorf("that is type *SnapshotResponsebut is not nil && this == nil")
}
if this.Success != nil && that1.Success != nil {
if *this.Success != *that1.Success {
return fmt35.Errorf("Success this(%v) Not Equal that(%v)", *this.Success, *that1.Success)
}
} else if this.Success != nil {
return fmt35.Errorf("this.Success == nil && that.Success != nil")
} else if that1.Success != nil {
return fmt35.Errorf("Success this(%v) Not Equal that(%v)", this.Success, that1.Success)
}
if !bytes8.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return fmt35.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
}
return nil
}
func (this *SnapshotResponse) Equal(that interface{}) bool {
if that == nil {
if this == nil {
return true
}
return false
}
that1, ok := that.(*SnapshotResponse)
if !ok {
return false
}
if that1 == nil {
if this == nil {
return true
}
return false
} else if this == nil {
return false
}
if this.Success != nil && that1.Success != nil {
if *this.Success != *that1.Success {
return false
}
} else if this.Success != nil {
return false
} else if that1.Success != nil {
return false
}
if !bytes8.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false
}
return true
}

View File

@ -1,19 +0,0 @@
package protobuf;
import "code.google.com/p/gogoprotobuf/gogoproto/gogo.proto";
option (gogoproto.gostring_all) = true;
option (gogoproto.equal_all) = true;
option (gogoproto.verbose_equal_all) = true;
option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
option (gogoproto.populate_all) = true;
option (gogoproto.testgen_all) = true;
option (gogoproto.benchgen_all) = true;
option (gogoproto.marshaler_all) = true;
option (gogoproto.sizer_all) = true;
option (gogoproto.unmarshaler_all) = true;
message SnapshotResponse {
required bool Success=1;
}

View File

@ -1,122 +0,0 @@
package raft
import (
"io"
"io/ioutil"
"code.google.com/p/gogoprotobuf/proto"
"github.com/influxdb/influxdb/_vendor/raft/protobuf"
)
// The request sent to a server to vote for a candidate to become a leader.
type RequestVoteRequest struct {
peer *Peer
Term uint64
LastLogIndex uint64
LastLogTerm uint64
CandidateName string
}
// The response returned from a server after a vote for a candidate to become a leader.
type RequestVoteResponse struct {
peer *Peer
Term uint64
VoteGranted bool
}
// Creates a new RequestVote request.
func newRequestVoteRequest(term uint64, candidateName string, lastLogIndex uint64, lastLogTerm uint64) *RequestVoteRequest {
return &RequestVoteRequest{
Term: term,
LastLogIndex: lastLogIndex,
LastLogTerm: lastLogTerm,
CandidateName: candidateName,
}
}
// Encodes the RequestVoteRequest to a buffer. Returns the number of bytes
// written and any error that may have occurred.
func (req *RequestVoteRequest) Encode(w io.Writer) (int, error) {
pb := &protobuf.RequestVoteRequest{
Term: proto.Uint64(req.Term),
LastLogIndex: proto.Uint64(req.LastLogIndex),
LastLogTerm: proto.Uint64(req.LastLogTerm),
CandidateName: proto.String(req.CandidateName),
}
p, err := proto.Marshal(pb)
if err != nil {
return -1, err
}
return w.Write(p)
}
// Decodes the RequestVoteRequest from a buffer. Returns the number of bytes read and
// any error that occurs.
func (req *RequestVoteRequest) Decode(r io.Reader) (int, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return -1, err
}
totalBytes := len(data)
pb := &protobuf.RequestVoteRequest{}
if err = proto.Unmarshal(data, pb); err != nil {
return -1, err
}
req.Term = pb.GetTerm()
req.LastLogIndex = pb.GetLastLogIndex()
req.LastLogTerm = pb.GetLastLogTerm()
req.CandidateName = pb.GetCandidateName()
return totalBytes, nil
}
// Creates a new RequestVote response.
func newRequestVoteResponse(term uint64, voteGranted bool) *RequestVoteResponse {
return &RequestVoteResponse{
Term: term,
VoteGranted: voteGranted,
}
}
// Encodes the RequestVoteResponse to a buffer. Returns the number of bytes
// written and any error that may have occurred.
func (resp *RequestVoteResponse) Encode(w io.Writer) (int, error) {
pb := &protobuf.RequestVoteResponse{
Term: proto.Uint64(resp.Term),
VoteGranted: proto.Bool(resp.VoteGranted),
}
p, err := proto.Marshal(pb)
if err != nil {
return -1, err
}
return w.Write(p)
}
// Decodes the RequestVoteResponse from a buffer. Returns the number of bytes read and
// any error that occurs.
func (resp *RequestVoteResponse) Decode(r io.Reader) (int, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return 0, err
}
totalBytes := len(data)
pb := &protobuf.RequestVoteResponse{}
if err = proto.Unmarshal(data, pb); err != nil {
return -1, err
}
resp.Term = pb.GetTerm()
resp.VoteGranted = pb.GetVoteGranted()
return totalBytes, nil
}

File diff suppressed because it is too large Load Diff

View File

@ -1,722 +0,0 @@
package raft
import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"sync"
"testing"
"time"
)
//--------------------------------------
// Request Vote
//--------------------------------------
// Ensure that we can request a vote from a server that has not voted.
func TestServerRequestVote(t *testing.T) {
server := newTestServer("1", &testTransporter{})
server.Start()
if _, err := server.Do(&DefaultJoinCommand{Name: server.Name()}); err != nil {
t.Fatalf("Server %s unable to join: %v", server.Name(), err)
}
defer server.Stop()
resp := server.RequestVote(newRequestVoteRequest(1, "foo", 1, 0))
if resp.Term != 1 || !resp.VoteGranted {
t.Fatalf("Invalid request vote response: %v/%v", resp.Term, resp.VoteGranted)
}
}
// // Ensure that a vote request is denied if it comes from an old term.
func TestServerRequestVoteDeniedForStaleTerm(t *testing.T) {
s := newTestServer("1", &testTransporter{})
s.Start()
if _, err := s.Do(&DefaultJoinCommand{Name: s.Name()}); err != nil {
t.Fatalf("Server %s unable to join: %v", s.Name(), err)
}
s.(*server).mutex.Lock()
s.(*server).currentTerm = 2
s.(*server).mutex.Unlock()
defer s.Stop()
resp := s.RequestVote(newRequestVoteRequest(1, "foo", 1, 0))
if resp.Term != 2 || resp.VoteGranted {
t.Fatalf("Invalid request vote response: %v/%v", resp.Term, resp.VoteGranted)
}
if s.Term() != 2 && s.State() != Follower {
t.Fatalf("Server did not update term and demote: %v / %v", s.Term(), s.State())
}
}
// Ensure that a vote request is denied if we've already voted for a different candidate.
func TestServerRequestVoteDeniedIfAlreadyVoted(t *testing.T) {
s := newTestServer("1", &testTransporter{})
s.Start()
if _, err := s.Do(&DefaultJoinCommand{Name: s.Name()}); err != nil {
t.Fatalf("Server %s unable to join: %v", s.Name(), err)
}
s.(*server).mutex.Lock()
s.(*server).currentTerm = 2
s.(*server).mutex.Unlock()
defer s.Stop()
resp := s.RequestVote(newRequestVoteRequest(2, "foo", 1, 0))
if resp.Term != 2 || !resp.VoteGranted {
t.Fatalf("First vote should not have been denied")
}
resp = s.RequestVote(newRequestVoteRequest(2, "bar", 1, 0))
if resp.Term != 2 || resp.VoteGranted {
t.Fatalf("Second vote should have been denied")
}
}
// Ensure that a vote request is approved if vote occurs in a new term.
func TestServerRequestVoteApprovedIfAlreadyVotedInOlderTerm(t *testing.T) {
s := newTestServer("1", &testTransporter{})
s.Start()
if _, err := s.Do(&DefaultJoinCommand{Name: s.Name()}); err != nil {
t.Fatalf("Server %s unable to join: %v", s.Name(), err)
}
time.Sleep(time.Millisecond * 100)
s.(*server).mutex.Lock()
s.(*server).currentTerm = 2
s.(*server).mutex.Unlock()
defer s.Stop()
resp := s.RequestVote(newRequestVoteRequest(2, "foo", 2, 1))
if resp.Term != 2 || !resp.VoteGranted || s.VotedFor() != "foo" {
t.Fatalf("First vote should not have been denied")
}
resp = s.RequestVote(newRequestVoteRequest(3, "bar", 2, 1))
if resp.Term != 3 || !resp.VoteGranted || s.VotedFor() != "bar" {
t.Fatalf("Second vote should have been approved")
}
}
// Ensure that a vote request is denied if the log is out of date.
func TestServerRequestVoteDenyIfCandidateLogIsBehind(t *testing.T) {
tmpLog := newLog()
e0, _ := newLogEntry(tmpLog, nil, 1, 1, &testCommand1{Val: "foo", I: 20})
e1, _ := newLogEntry(tmpLog, nil, 2, 1, &testCommand2{X: 100})
e2, _ := newLogEntry(tmpLog, nil, 3, 2, &testCommand1{Val: "bar", I: 0})
s := newTestServerWithLog("1", &testTransporter{}, []*LogEntry{e0, e1, e2})
// start as a follower with term 2 and index 3
s.Start()
defer s.Stop()
// request vote from term 3 with last log entry 2, 2
resp := s.RequestVote(newRequestVoteRequest(3, "foo", 2, 2))
if resp.Term != 3 || resp.VoteGranted {
t.Fatalf("Stale index vote should have been denied [%v/%v]", resp.Term, resp.VoteGranted)
}
// request vote from term 2 with last log entry 2, 3
resp = s.RequestVote(newRequestVoteRequest(2, "foo", 3, 2))
if resp.Term != 3 || resp.VoteGranted {
t.Fatalf("Stale term vote should have been denied [%v/%v]", resp.Term, resp.VoteGranted)
}
// request vote from term 3 with last log entry 2, 3
resp = s.RequestVote(newRequestVoteRequest(3, "foo", 3, 2))
if resp.Term != 3 || !resp.VoteGranted {
t.Fatalf("Matching log vote should have been granted")
}
// request vote from term 3 with last log entry 2, 4
resp = s.RequestVote(newRequestVoteRequest(3, "foo", 4, 2))
if resp.Term != 3 || !resp.VoteGranted {
t.Fatalf("Ahead-of-log vote should have been granted")
}
}
func TestProcessVoteResponse(t *testing.T) {
// server Term: 0, status: Leader
// response Term : 1, granted
// Expectation: not success
// Server Term 1 status:Leader
server := &server{}
server.eventDispatcher = newEventDispatcher(server)
server.currentTerm = 0
server.state = Leader
response := &RequestVoteResponse{
VoteGranted: true,
Term: 1,
}
if success := server.processVoteResponse(response); success {
t.Fatal("Process should fail if the resp's term is larger than server's")
}
if server.state != Follower {
t.Fatal("Server should stepdown")
}
// server Term: 1, status: Follower
// response Term: 2, granted
// Expectation: not success
response.Term = 2
if success := server.processVoteResponse(response); success {
t.Fatal("Process should fail if the resp's term is larger than server's")
}
if server.state != Follower {
t.Fatal("Server should still be Follower")
}
server.currentTerm = 2
// server Term: 2, status: Follower
// response Term: 2
// Expectation: success
if success := server.processVoteResponse(response); !success {
t.Fatal("Process should success if the server's term is larger than resp's")
}
}
// //--------------------------------------
// // Promotion
// //--------------------------------------
// // Ensure that we can self-promote a server to candidate, obtain votes and become a fearless leader.
func TestServerPromoteSelf(t *testing.T) {
e0, _ := newLogEntry(newLog(), nil, 1, 1, &testCommand1{Val: "foo", I: 20})
s := newTestServerWithLog("1", &testTransporter{}, []*LogEntry{e0})
// start as a follower
s.Start()
defer s.Stop()
time.Sleep(2 * testElectionTimeout)
if s.State() != Leader {
t.Fatalf("Server self-promotion failed: %v", s.State())
}
}
//Ensure that we can promote a server within a cluster to a leader.
func TestServerPromote(t *testing.T) {
lookup := map[string]Server{}
transporter := &testTransporter{}
transporter.sendVoteRequestFunc = func(s Server, peer *Peer, req *RequestVoteRequest) *RequestVoteResponse {
return lookup[peer.Name].RequestVote(req)
}
transporter.sendAppendEntriesRequestFunc = func(s Server, peer *Peer, req *AppendEntriesRequest) *AppendEntriesResponse {
return lookup[peer.Name].AppendEntries(req)
}
servers := newTestCluster([]string{"1", "2", "3"}, transporter, lookup)
servers[0].Start()
servers[1].Start()
servers[2].Start()
time.Sleep(2 * testElectionTimeout)
if servers[0].State() != Leader && servers[1].State() != Leader && servers[2].State() != Leader {
t.Fatalf("No leader elected: (%s, %s, %s)", servers[0].State(), servers[1].State(), servers[2].State())
}
for _, s := range servers {
s.Stop()
}
}
//--------------------------------------
// Append Entries
//--------------------------------------
// Ensure we can append entries to a server.
func TestServerAppendEntries(t *testing.T) {
s := newTestServer("1", &testTransporter{})
s.SetHeartbeatInterval(time.Second * 10)
s.Start()
defer s.Stop()
// Append single entry.
e, _ := newLogEntry(nil, nil, 1, 1, &testCommand1{Val: "foo", I: 10})
entries := []*LogEntry{e}
resp := s.AppendEntries(newAppendEntriesRequest(1, 0, 0, 0, "ldr", entries))
if resp.Term() != 1 || !resp.Success() {
t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
}
if index, term := s.(*server).log.commitInfo(); index != 0 || term != 0 {
t.Fatalf("Invalid commit info [IDX=%v, TERM=%v]", index, term)
}
// Append multiple entries + commit the last one.
e1, _ := newLogEntry(nil, nil, 2, 1, &testCommand1{Val: "bar", I: 20})
e2, _ := newLogEntry(nil, nil, 3, 1, &testCommand1{Val: "baz", I: 30})
entries = []*LogEntry{e1, e2}
resp = s.AppendEntries(newAppendEntriesRequest(1, 1, 1, 1, "ldr", entries))
if resp.Term() != 1 || !resp.Success() {
t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
}
if index, term := s.(*server).log.commitInfo(); index != 1 || term != 1 {
t.Fatalf("Invalid commit info [IDX=%v, TERM=%v]", index, term)
}
// Send zero entries and commit everything.
resp = s.AppendEntries(newAppendEntriesRequest(2, 3, 1, 3, "ldr", []*LogEntry{}))
if resp.Term() != 2 || !resp.Success() {
t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
}
if index, term := s.(*server).log.commitInfo(); index != 3 || term != 1 {
t.Fatalf("Invalid commit info [IDX=%v, TERM=%v]", index, term)
}
}
//Ensure that entries with stale terms are rejected.
func TestServerAppendEntriesWithStaleTermsAreRejected(t *testing.T) {
s := newTestServer("1", &testTransporter{})
s.Start()
defer s.Stop()
s.(*server).mutex.Lock()
s.(*server).currentTerm = 2
s.(*server).mutex.Unlock()
// Append single entry.
e, _ := newLogEntry(nil, nil, 1, 1, &testCommand1{Val: "foo", I: 10})
entries := []*LogEntry{e}
resp := s.AppendEntries(newAppendEntriesRequest(1, 0, 0, 0, "ldr", entries))
if resp.Term() != 2 || resp.Success() {
t.Fatalf("AppendEntries should have failed: %v/%v", resp.Term, resp.Success)
}
if index, term := s.(*server).log.commitInfo(); index != 0 || term != 0 {
t.Fatalf("Invalid commit info [IDX=%v, TERM=%v]", index, term)
}
}
// Ensure that we reject entries if the commit log is different.
func TestServerAppendEntriesRejectedIfAlreadyCommitted(t *testing.T) {
s := newTestServer("1", &testTransporter{})
s.Start()
defer s.Stop()
// Append single entry + commit.
e1, _ := newLogEntry(nil, nil, 1, 1, &testCommand1{Val: "foo", I: 10})
e2, _ := newLogEntry(nil, nil, 2, 1, &testCommand1{Val: "foo", I: 15})
entries := []*LogEntry{e1, e2}
resp := s.AppendEntries(newAppendEntriesRequest(1, 0, 0, 2, "ldr", entries))
if resp.Term() != 1 || !resp.Success() {
t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
}
// Append entry again (post-commit).
e, _ := newLogEntry(nil, nil, 2, 1, &testCommand1{Val: "bar", I: 20})
entries = []*LogEntry{e}
resp = s.AppendEntries(newAppendEntriesRequest(1, 2, 1, 1, "ldr", entries))
if resp.Term() != 1 || resp.Success() {
t.Fatalf("AppendEntries should have failed: %v/%v", resp.Term, resp.Success)
}
}
// Ensure that we uncommitted entries are rolled back if new entries overwrite them.
func TestServerAppendEntriesOverwritesUncommittedEntries(t *testing.T) {
s := newTestServer("1", &testTransporter{})
s.Start()
defer s.Stop()
entry1, _ := newLogEntry(s.(*server).log, nil, 1, 1, &testCommand1{Val: "foo", I: 10})
entry2, _ := newLogEntry(s.(*server).log, nil, 2, 1, &testCommand1{Val: "foo", I: 15})
entry3, _ := newLogEntry(s.(*server).log, nil, 2, 2, &testCommand1{Val: "bar", I: 20})
// Append single entry + commit.
entries := []*LogEntry{entry1, entry2}
resp := s.AppendEntries(newAppendEntriesRequest(1, 0, 0, 1, "ldr", entries))
if resp.Term() != 1 || !resp.Success() || s.(*server).log.commitIndex != 1 {
t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
}
for i, entry := range s.(*server).log.entries {
if entry.Term() != entries[i].Term() || entry.Index() != entries[i].Index() || !bytes.Equal(entry.Command(), entries[i].Command()) {
t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
}
}
// Append entry that overwrites the second (uncommitted) entry.
entries = []*LogEntry{entry3}
resp = s.AppendEntries(newAppendEntriesRequest(2, 1, 1, 2, "ldr", entries))
if resp.Term() != 2 || !resp.Success() || s.(*server).log.commitIndex != 2 {
t.Fatalf("AppendEntries should have succeeded: %v/%v", resp.Term, resp.Success)
}
entries = []*LogEntry{entry1, entry3}
for i, entry := range s.(*server).log.entries {
if entry.Term() != entries[i].Term() || entry.Index() != entries[i].Index() || !bytes.Equal(entry.Command(), entries[i].Command()) {
t.Fatalf("AppendEntries failed: %v/%v", resp.Term, resp.Success)
}
}
}
//--------------------------------------
// Command Execution
//--------------------------------------
// Ensure that a follower cannot execute a command.
func TestServerDenyCommandExecutionWhenFollower(t *testing.T) {
s := newTestServer("1", &testTransporter{})
s.Start()
defer s.Stop()
var err error
if _, err = s.Do(&testCommand1{Val: "foo", I: 10}); err != NotLeaderError {
t.Fatalf("Expected error: %v, got: %v", NotLeaderError, err)
}
}
//--------------------------------------
// Recovery
//--------------------------------------
// Ensure that a follower cannot execute a command.
func TestServerRecoverFromPreviousLogAndConf(t *testing.T) {
// Initialize the servers.
var mutex sync.RWMutex
servers := map[string]Server{}
transporter := &testTransporter{}
transporter.sendVoteRequestFunc = func(s Server, peer *Peer, req *RequestVoteRequest) *RequestVoteResponse {
mutex.RLock()
target := servers[peer.Name]
mutex.RUnlock()
b, _ := json.Marshal(req)
clonedReq := &RequestVoteRequest{}
json.Unmarshal(b, clonedReq)
return target.RequestVote(clonedReq)
}
transporter.sendAppendEntriesRequestFunc = func(s Server, peer *Peer, req *AppendEntriesRequest) *AppendEntriesResponse {
mutex.RLock()
target := servers[peer.Name]
mutex.RUnlock()
b, _ := json.Marshal(req)
clonedReq := &AppendEntriesRequest{}
json.Unmarshal(b, clonedReq)
return target.AppendEntries(clonedReq)
}
disTransporter := &testTransporter{}
disTransporter.sendVoteRequestFunc = func(s Server, peer *Peer, req *RequestVoteRequest) *RequestVoteResponse {
return nil
}
disTransporter.sendAppendEntriesRequestFunc = func(s Server, peer *Peer, req *AppendEntriesRequest) *AppendEntriesResponse {
return nil
}
var names []string
var paths = make(map[string]string)
n := 5
// add n servers
for i := 1; i <= n; i++ {
names = append(names, strconv.Itoa(i))
}
var leader Server
for _, name := range names {
s := newTestServer(name, transporter)
mutex.Lock()
servers[name] = s
mutex.Unlock()
paths[name] = s.Path()
if name == "1" {
leader = s
s.SetHeartbeatInterval(testHeartbeatInterval)
s.Start()
time.Sleep(testHeartbeatInterval)
} else {
s.SetElectionTimeout(testElectionTimeout)
s.SetHeartbeatInterval(testHeartbeatInterval)
s.Start()
time.Sleep(testHeartbeatInterval)
}
if _, err := leader.Do(&DefaultJoinCommand{Name: name}); err != nil {
t.Fatalf("Unable to join server[%s]: %v", name, err)
}
}
// commit some commands
for i := 0; i < 10; i++ {
if _, err := leader.Do(&testCommand2{X: 1}); err != nil {
t.Fatalf("cannot commit command: %s", err.Error())
}
}
time.Sleep(2 * testHeartbeatInterval)
for _, name := range names {
s := servers[name]
if s.CommitIndex() != 16 {
t.Fatalf("%s commitIndex is invalid [%d/%d]", name, s.CommitIndex(), 16)
}
s.Stop()
}
for _, name := range names {
// with old path and disable transportation
s := newTestServerWithPath(name, disTransporter, paths[name])
servers[name] = s
s.Start()
// should only commit to the last join command
if s.CommitIndex() != 6 {
t.Fatalf("%s recover phase 1 commitIndex is invalid [%d/%d]", name, s.CommitIndex(), 6)
}
// peer conf should be recovered
if len(s.Peers()) != 4 {
t.Fatalf("%s recover phase 1 peer failed! [%d/%d]", name, len(s.Peers()), 4)
}
}
// let nodes talk to each other
for _, name := range names {
servers[name].SetTransporter(transporter)
}
time.Sleep(2 * testElectionTimeout)
// should commit to the previous index + 1(nop command when new leader elected)
for _, name := range names {
s := servers[name]
if s.CommitIndex() != 17 {
t.Fatalf("%s commitIndex is invalid [%d/%d]", name, s.CommitIndex(), 17)
}
s.Stop()
}
}
//--------------------------------------
// Membership
//--------------------------------------
// Ensure that we can start a single server and append to its log.
func TestServerSingleNode(t *testing.T) {
s := newTestServer("1", &testTransporter{})
if s.State() != Stopped {
t.Fatalf("Unexpected server state: %v", s.State())
}
s.Start()
time.Sleep(testHeartbeatInterval)
// Join the server to itself.
if _, err := s.Do(&DefaultJoinCommand{Name: "1"}); err != nil {
t.Fatalf("Unable to join: %v", err)
}
debugln("finish command")
if s.State() != Leader {
t.Fatalf("Unexpected server state: %v", s.State())
}
s.Stop()
if s.State() != Stopped {
t.Fatalf("Unexpected server state: %v", s.State())
}
}
// Ensure that we can start multiple servers and determine a leader.
func TestServerMultiNode(t *testing.T) {
// Initialize the servers.
var mutex sync.RWMutex
servers := map[string]Server{}
transporter := &testTransporter{}
transporter.sendVoteRequestFunc = func(s Server, peer *Peer, req *RequestVoteRequest) *RequestVoteResponse {
mutex.RLock()
target := servers[peer.Name]
mutex.RUnlock()
b, _ := json.Marshal(req)
clonedReq := &RequestVoteRequest{}
json.Unmarshal(b, clonedReq)
c := make(chan *RequestVoteResponse)
go func() {
c <- target.RequestVote(clonedReq)
}()
select {
case resp := <-c:
return resp
case <-time.After(time.Millisecond * 200):
return nil
}
}
transporter.sendAppendEntriesRequestFunc = func(s Server, peer *Peer, req *AppendEntriesRequest) *AppendEntriesResponse {
mutex.RLock()
target := servers[peer.Name]
mutex.RUnlock()
b, _ := json.Marshal(req)
clonedReq := &AppendEntriesRequest{}
json.Unmarshal(b, clonedReq)
c := make(chan *AppendEntriesResponse)
go func() {
c <- target.AppendEntries(clonedReq)
}()
select {
case resp := <-c:
return resp
case <-time.After(time.Millisecond * 200):
return nil
}
}
disTransporter := &testTransporter{}
disTransporter.sendVoteRequestFunc = func(s Server, peer *Peer, req *RequestVoteRequest) *RequestVoteResponse {
return nil
}
disTransporter.sendAppendEntriesRequestFunc = func(s Server, peer *Peer, req *AppendEntriesRequest) *AppendEntriesResponse {
return nil
}
var names []string
n := 5
// add n servers
for i := 1; i <= n; i++ {
names = append(names, strconv.Itoa(i))
}
var leader Server
for _, name := range names {
s := newTestServer(name, transporter)
defer s.Stop()
mutex.Lock()
servers[name] = s
mutex.Unlock()
if name == "1" {
leader = s
s.SetHeartbeatInterval(testHeartbeatInterval)
s.Start()
time.Sleep(testHeartbeatInterval)
} else {
s.SetElectionTimeout(testElectionTimeout)
s.SetHeartbeatInterval(testHeartbeatInterval)
s.Start()
time.Sleep(testHeartbeatInterval)
}
if _, err := leader.Do(&DefaultJoinCommand{Name: name}); err != nil {
t.Fatalf("Unable to join server[%s]: %v", name, err)
}
}
time.Sleep(2 * testElectionTimeout)
// Check that two peers exist on leader.
mutex.RLock()
if leader.MemberCount() != n {
t.Fatalf("Expected member count to be %v, got %v", n, leader.MemberCount())
}
if servers["2"].State() == Leader || servers["3"].State() == Leader {
t.Fatalf("Expected leader should be 1: 2=%v, 3=%v\n", servers["2"].State(), servers["3"].State())
}
mutex.RUnlock()
for i := 0; i < 20; i++ {
retry := 0
fmt.Println("Round ", i)
num := strconv.Itoa(i%(len(servers)) + 1)
num_1 := strconv.Itoa((i+3)%(len(servers)) + 1)
toStop := servers[num]
toStop_1 := servers[num_1]
// Stop the first server and wait for a re-election.
time.Sleep(2 * testElectionTimeout)
debugln("Disconnect ", toStop.Name())
debugln("disconnect ", num, " ", num_1)
toStop.SetTransporter(disTransporter)
toStop_1.SetTransporter(disTransporter)
time.Sleep(2 * testElectionTimeout)
// Check that either server 2 or 3 is the leader now.
//mutex.Lock()
leader := 0
for key, value := range servers {
debugln("Play begin")
if key != num && key != num_1 {
if value.State() == Leader {
debugln("Found leader")
for i := 0; i < 10; i++ {
debugln("[Test] do ", value.Name())
if _, err := value.Do(&testCommand2{X: 1}); err != nil {
break
}
debugln("[Test] Done")
}
debugln("Leader is ", value.Name(), " Index ", value.(*server).log.commitIndex)
}
debugln("Not Found leader")
}
}
for {
for key, value := range servers {
if key != num && key != num_1 {
if value.State() == Leader {
leader++
}
debugln(value.Name(), " ", value.(*server).Term(), " ", value.State())
}
}
if leader > 1 {
if retry < 300 {
debugln("retry")
retry++
leader = 0
time.Sleep(2 * testElectionTimeout)
continue
}
t.Fatalf("wrong leader number %v", leader)
}
if leader == 0 {
if retry < 300 {
retry++
fmt.Println("retry 0")
leader = 0
time.Sleep(2 * testElectionTimeout)
continue
}
t.Fatalf("wrong leader number %v", leader)
}
if leader == 1 {
break
}
}
//mutex.Unlock()
toStop.SetTransporter(transporter)
toStop_1.SetTransporter(transporter)
}
}

View File

@ -1,304 +0,0 @@
package raft
import (
"encoding/json"
"fmt"
"hash/crc32"
"io"
"io/ioutil"
"os"
"code.google.com/p/gogoprotobuf/proto"
"github.com/influxdb/influxdb/_vendor/raft/protobuf"
)
// Snapshot represents an in-memory representation of the current state of the system.
type Snapshot struct {
LastIndex uint64 `json:"lastIndex"`
LastTerm uint64 `json:"lastTerm"`
// Cluster configuration.
Peers []*Peer `json:"peers"`
State []byte `json:"state"`
Path string `json:"path"`
}
// The request sent to a server to start from the snapshot.
type SnapshotRecoveryRequest struct {
LeaderName string
LastIndex uint64
LastTerm uint64
Peers []*Peer
State []byte
}
// The response returned from a server appending entries to the log.
type SnapshotRecoveryResponse struct {
Term uint64
Success bool
CommitIndex uint64
}
// The request sent to a server to start from the snapshot.
type SnapshotRequest struct {
LeaderName string
LastIndex uint64
LastTerm uint64
}
// The response returned if the follower entered snapshot state
type SnapshotResponse struct {
Success bool `json:"success"`
}
// save writes the snapshot to file.
func (ss *Snapshot) save() error {
// Open the file for writing.
file, err := os.OpenFile(ss.Path, os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
return err
}
defer file.Close()
// Serialize to JSON.
b, err := json.Marshal(ss)
if err != nil {
return err
}
// Generate checksum and write it to disk.
checksum := crc32.ChecksumIEEE(b)
if _, err = fmt.Fprintf(file, "%08x\n", checksum); err != nil {
return err
}
// Write the snapshot to disk.
if _, err = file.Write(b); err != nil {
return err
}
// Ensure that the snapshot has been flushed to disk before continuing.
if err := file.Sync(); err != nil {
return err
}
return nil
}
// remove deletes the snapshot file.
func (ss *Snapshot) remove() error {
if err := os.Remove(ss.Path); err != nil {
return err
}
return nil
}
// Creates a new Snapshot request.
func newSnapshotRecoveryRequest(leaderName string, snapshot *Snapshot) *SnapshotRecoveryRequest {
return &SnapshotRecoveryRequest{
LeaderName: leaderName,
LastIndex: snapshot.LastIndex,
LastTerm: snapshot.LastTerm,
Peers: snapshot.Peers,
State: snapshot.State,
}
}
// Encodes the SnapshotRecoveryRequest to a buffer. Returns the number of bytes
// written and any error that may have occurred.
func (req *SnapshotRecoveryRequest) Encode(w io.Writer) (int, error) {
protoPeers := make([]*protobuf.SnapshotRecoveryRequest_Peer, len(req.Peers))
for i, peer := range req.Peers {
protoPeers[i] = &protobuf.SnapshotRecoveryRequest_Peer{
Name: proto.String(peer.Name),
ConnectionString: proto.String(peer.ConnectionString),
}
}
pb := &protobuf.SnapshotRecoveryRequest{
LeaderName: proto.String(req.LeaderName),
LastIndex: proto.Uint64(req.LastIndex),
LastTerm: proto.Uint64(req.LastTerm),
Peers: protoPeers,
State: req.State,
}
p, err := proto.Marshal(pb)
if err != nil {
return -1, err
}
return w.Write(p)
}
// Decodes the SnapshotRecoveryRequest from a buffer. Returns the number of bytes read and
// any error that occurs.
func (req *SnapshotRecoveryRequest) Decode(r io.Reader) (int, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return 0, err
}
totalBytes := len(data)
pb := &protobuf.SnapshotRecoveryRequest{}
if err = proto.Unmarshal(data, pb); err != nil {
return -1, err
}
req.LeaderName = pb.GetLeaderName()
req.LastIndex = pb.GetLastIndex()
req.LastTerm = pb.GetLastTerm()
req.State = pb.GetState()
req.Peers = make([]*Peer, len(pb.Peers))
for i, peer := range pb.Peers {
req.Peers[i] = &Peer{
Name: peer.GetName(),
ConnectionString: peer.GetConnectionString(),
}
}
return totalBytes, nil
}
// Creates a new Snapshot response.
func newSnapshotRecoveryResponse(term uint64, success bool, commitIndex uint64) *SnapshotRecoveryResponse {
return &SnapshotRecoveryResponse{
Term: term,
Success: success,
CommitIndex: commitIndex,
}
}
// Encode writes the response to a writer.
// Returns the number of bytes written and any error that occurs.
func (req *SnapshotRecoveryResponse) Encode(w io.Writer) (int, error) {
pb := &protobuf.SnapshotRecoveryResponse{
Term: proto.Uint64(req.Term),
Success: proto.Bool(req.Success),
CommitIndex: proto.Uint64(req.CommitIndex),
}
p, err := proto.Marshal(pb)
if err != nil {
return -1, err
}
return w.Write(p)
}
// Decodes the SnapshotRecoveryResponse from a buffer.
func (req *SnapshotRecoveryResponse) Decode(r io.Reader) (int, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return 0, err
}
totalBytes := len(data)
pb := &protobuf.SnapshotRecoveryResponse{}
if err := proto.Unmarshal(data, pb); err != nil {
return -1, err
}
req.Term = pb.GetTerm()
req.Success = pb.GetSuccess()
req.CommitIndex = pb.GetCommitIndex()
return totalBytes, nil
}
// Creates a new Snapshot request.
func newSnapshotRequest(leaderName string, snapshot *Snapshot) *SnapshotRequest {
return &SnapshotRequest{
LeaderName: leaderName,
LastIndex: snapshot.LastIndex,
LastTerm: snapshot.LastTerm,
}
}
// Encodes the SnapshotRequest to a buffer. Returns the number of bytes
// written and any error that may have occurred.
func (req *SnapshotRequest) Encode(w io.Writer) (int, error) {
pb := &protobuf.SnapshotRequest{
LeaderName: proto.String(req.LeaderName),
LastIndex: proto.Uint64(req.LastIndex),
LastTerm: proto.Uint64(req.LastTerm),
}
p, err := proto.Marshal(pb)
if err != nil {
return -1, err
}
return w.Write(p)
}
// Decodes the SnapshotRequest from a buffer. Returns the number of bytes read and
// any error that occurs.
func (req *SnapshotRequest) Decode(r io.Reader) (int, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return 0, err
}
totalBytes := len(data)
pb := &protobuf.SnapshotRequest{}
if err := proto.Unmarshal(data, pb); err != nil {
return -1, err
}
req.LeaderName = pb.GetLeaderName()
req.LastIndex = pb.GetLastIndex()
req.LastTerm = pb.GetLastTerm()
return totalBytes, nil
}
// Creates a new Snapshot response.
func newSnapshotResponse(success bool) *SnapshotResponse {
return &SnapshotResponse{
Success: success,
}
}
// Encodes the SnapshotResponse to a buffer. Returns the number of bytes
// written and any error that may have occurred.
func (resp *SnapshotResponse) Encode(w io.Writer) (int, error) {
pb := &protobuf.SnapshotResponse{
Success: proto.Bool(resp.Success),
}
p, err := proto.Marshal(pb)
if err != nil {
return -1, err
}
return w.Write(p)
}
// Decodes the SnapshotResponse from a buffer. Returns the number of bytes read and
// any error that occurs.
func (resp *SnapshotResponse) Decode(r io.Reader) (int, error) {
data, err := ioutil.ReadAll(r)
if err != nil {
return 0, err
}
totalBytes := len(data)
pb := &protobuf.SnapshotResponse{}
if err := proto.Unmarshal(data, pb); err != nil {
return -1, err
}
resp.Success = pb.GetSuccess()
return totalBytes, nil
}

View File

@ -1,106 +0,0 @@
package raft
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
// Ensure that a snapshot occurs when there are existing logs.
func TestSnapshot(t *testing.T) {
runServerWithMockStateMachine(Leader, func(s Server, m *mock.Mock) {
m.On("Save").Return([]byte("foo"), nil)
m.On("Recovery", []byte("foo")).Return(nil)
s.Do(&testCommand1{})
err := s.TakeSnapshot()
assert.NoError(t, err)
assert.Equal(t, s.(*server).snapshot.LastIndex, uint64(2))
// Repeat to make sure new snapshot gets created.
s.Do(&testCommand1{})
err = s.TakeSnapshot()
assert.NoError(t, err)
assert.Equal(t, s.(*server).snapshot.LastIndex, uint64(4))
// Restart server.
s.Stop()
// Recover from snapshot.
err = s.LoadSnapshot()
assert.NoError(t, err)
s.Start()
})
}
// Ensure that a new server can recover from previous snapshot with log
func TestSnapshotRecovery(t *testing.T) {
runServerWithMockStateMachine(Leader, func(s Server, m *mock.Mock) {
m.On("Save").Return([]byte("foo"), nil)
m.On("Recovery", []byte("foo")).Return(nil)
s.Do(&testCommand1{})
err := s.TakeSnapshot()
assert.NoError(t, err)
assert.Equal(t, s.(*server).snapshot.LastIndex, uint64(2))
// Repeat to make sure new snapshot gets created.
s.Do(&testCommand1{})
// Stop the old server
s.Stop()
// create a new server with previous log and snapshot
newS, err := NewServer("1", s.Path(), &testTransporter{}, s.StateMachine(), nil, "")
// Recover from snapshot.
err = newS.LoadSnapshot()
assert.NoError(t, err)
newS.Start()
defer newS.Stop()
// wait for it to become leader
time.Sleep(time.Second)
// ensure server load the previous log
assert.Equal(t, len(newS.LogEntries()), 3, "")
})
}
// Ensure that a snapshot request can be sent and received.
func TestSnapshotRequest(t *testing.T) {
runServerWithMockStateMachine(Follower, func(s Server, m *mock.Mock) {
m.On("Recovery", []byte("bar")).Return(nil)
// Send snapshot request.
resp := s.RequestSnapshot(&SnapshotRequest{LastIndex: 5, LastTerm: 1})
assert.Equal(t, resp.Success, true)
assert.Equal(t, s.State(), Snapshotting)
// Send recovery request.
resp2 := s.SnapshotRecoveryRequest(&SnapshotRecoveryRequest{
LeaderName: "1",
LastIndex: 5,
LastTerm: 2,
Peers: make([]*Peer, 0),
State: []byte("bar"),
})
assert.Equal(t, resp2.Success, true)
})
}
func runServerWithMockStateMachine(state string, fn func(s Server, m *mock.Mock)) {
var m mockStateMachine
s := newTestServer("1", &testTransporter{})
s.(*server).stateMachine = &m
if err := s.Start(); err != nil {
panic("server start error: " + err.Error())
}
if state == Leader {
if _, err := s.Do(&DefaultJoinCommand{Name: s.Name()}); err != nil {
panic("unable to join server to self: " + err.Error())
}
}
defer s.Stop()
fn(s, &m.Mock)
}

View File

@ -1,9 +0,0 @@
package raft
// StateMachine is the interface for allowing the host application to save and
// recovery the state machine. This makes it possible to make snapshots
// and compact the log.
type StateMachine interface {
Save() ([]byte, error)
Recovery([]byte) error
}

View File

@ -1,19 +0,0 @@
package raft
import (
"github.com/stretchr/testify/mock"
)
type mockStateMachine struct {
mock.Mock
}
func (m *mockStateMachine) Save() ([]byte, error) {
args := m.Called()
return args.Get(0).([]byte), args.Error(1)
}
func (m *mockStateMachine) Recovery(b []byte) error {
args := m.Called(b)
return args.Error(0)
}

View File

@ -1,197 +0,0 @@
package raft
import (
"fmt"
"io/ioutil"
"os"
"time"
)
const (
testHeartbeatInterval = 50 * time.Millisecond
testElectionTimeout = 200 * time.Millisecond
)
const (
testListenerLoggerEnabled = false
)
func init() {
RegisterCommand(&testCommand1{})
RegisterCommand(&testCommand2{})
}
//------------------------------------------------------------------------------
//
// Helpers
//
//------------------------------------------------------------------------------
//--------------------------------------
// Logs
//--------------------------------------
func getLogPath() string {
f, _ := ioutil.TempFile("", "raft-log-")
f.Close()
os.Remove(f.Name())
return f.Name()
}
func setupLog(entries []*LogEntry) (*Log, string) {
f, _ := ioutil.TempFile("", "raft-log-")
for _, entry := range entries {
entry.Encode(f)
}
err := f.Close()
if err != nil {
panic(err)
}
log := newLog()
log.ApplyFunc = func(e *LogEntry, c Command) (interface{}, error) {
return nil, nil
}
if err := log.open(f.Name()); err != nil {
panic(err)
}
return log, f.Name()
}
//--------------------------------------
// Servers
//--------------------------------------
func newTestServer(name string, transporter Transporter) Server {
p, _ := ioutil.TempDir("", "raft-server-")
if err := os.MkdirAll(p, 0644); err != nil {
panic(err.Error())
}
server, _ := NewServer(name, p, transporter, nil, nil, "")
if testListenerLoggerEnabled {
fn := func(e Event) {
server := e.Source().(Server)
warnf("[%s] %s %v -> %v\n", server.Name(), e.Type(), e.PrevValue(), e.Value())
}
server.AddEventListener(StateChangeEventType, fn)
server.AddEventListener(LeaderChangeEventType, fn)
server.AddEventListener(TermChangeEventType, fn)
}
return server
}
func newTestServerWithPath(name string, transporter Transporter, p string) Server {
server, _ := NewServer(name, p, transporter, nil, nil, "")
return server
}
func newTestServerWithLog(name string, transporter Transporter, entries []*LogEntry) Server {
server := newTestServer(name, transporter)
f, err := os.Create(server.LogPath())
if err != nil {
panic(err)
}
for _, entry := range entries {
entry.Encode(f)
}
f.Close()
return server
}
func newTestCluster(names []string, transporter Transporter, lookup map[string]Server) []Server {
servers := []Server{}
e0, _ := newLogEntry(newLog(), nil, 1, 1, &testCommand1{Val: "foo", I: 20})
for _, name := range names {
if lookup[name] != nil {
panic(fmt.Sprintf("raft: Duplicate server in test cluster! %v", name))
}
server := newTestServerWithLog("1", transporter, []*LogEntry{e0})
server.SetElectionTimeout(testElectionTimeout)
servers = append(servers, server)
lookup[name] = server
}
for _, server := range servers {
server.SetHeartbeatInterval(testHeartbeatInterval)
server.Start()
for _, peer := range servers {
server.AddPeer(peer.Name(), "")
}
}
return servers
}
//--------------------------------------
// Transporter
//--------------------------------------
type testTransporter struct {
sendVoteRequestFunc func(server Server, peer *Peer, req *RequestVoteRequest) *RequestVoteResponse
sendAppendEntriesRequestFunc func(server Server, peer *Peer, req *AppendEntriesRequest) *AppendEntriesResponse
sendSnapshotRequestFunc func(server Server, peer *Peer, req *SnapshotRequest) *SnapshotResponse
}
func (t *testTransporter) SendVoteRequest(server Server, peer *Peer, req *RequestVoteRequest) *RequestVoteResponse {
return t.sendVoteRequestFunc(server, peer, req)
}
func (t *testTransporter) SendAppendEntriesRequest(server Server, peer *Peer, req *AppendEntriesRequest) *AppendEntriesResponse {
return t.sendAppendEntriesRequestFunc(server, peer, req)
}
func (t *testTransporter) SendSnapshotRequest(server Server, peer *Peer, req *SnapshotRequest) *SnapshotResponse {
return t.sendSnapshotRequestFunc(server, peer, req)
}
func (t *testTransporter) SendSnapshotRecoveryRequest(server Server, peer *Peer, req *SnapshotRecoveryRequest) *SnapshotRecoveryResponse {
return t.SendSnapshotRecoveryRequest(server, peer, req)
}
type testStateMachine struct {
saveFunc func() ([]byte, error)
recoveryFunc func([]byte) error
}
func (sm *testStateMachine) Save() ([]byte, error) {
return sm.saveFunc()
}
func (sm *testStateMachine) Recovery(state []byte) error {
return sm.recoveryFunc(state)
}
//--------------------------------------
// Command1
//--------------------------------------
type testCommand1 struct {
Val string `json:"val"`
I int `json:"i"`
}
func (c *testCommand1) CommandName() string {
return "cmd_1"
}
func (c *testCommand1) Apply(server Server) (interface{}, error) {
return nil, nil
}
//--------------------------------------
// Command2
//--------------------------------------
type testCommand2 struct {
X int `json:"x"`
}
func (c *testCommand2) CommandName() string {
return "cmd_2"
}
func (c *testCommand2) Apply(server Server) (interface{}, error) {
return nil, nil
}

View File

@ -1,16 +0,0 @@
package raft
//------------------------------------------------------------------------------
//
// Typedefs
//
//------------------------------------------------------------------------------
// Transporter is the interface for allowing the host application to transport
// requests to other nodes.
type Transporter interface {
SendVoteRequest(server Server, peer *Peer, req *RequestVoteRequest) *RequestVoteResponse
SendAppendEntriesRequest(server Server, peer *Peer, req *AppendEntriesRequest) *AppendEntriesResponse
SendSnapshotRequest(server Server, peer *Peer, req *SnapshotRequest) *SnapshotResponse
SendSnapshotRecoveryRequest(server Server, peer *Peer, req *SnapshotRecoveryRequest) *SnapshotRecoveryResponse
}

View File

@ -1,62 +0,0 @@
package raft
import (
"fmt"
"io"
"math/rand"
"os"
"time"
)
// uint64Slice implements sort interface
type uint64Slice []uint64
func (p uint64Slice) Len() int { return len(p) }
func (p uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// WriteFile writes data to a file named by filename.
// If the file does not exist, WriteFile creates it with permissions perm;
// otherwise WriteFile truncates it before writing.
// This is copied from ioutil.WriteFile with the addition of a Sync call to
// ensure the data reaches the disk.
func writeFileSynced(filename string, data []byte, perm os.FileMode) error {
f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
if err != nil {
return err
}
defer f.Close() // Idempotent
n, err := f.Write(data)
if err == nil && n < len(data) {
return io.ErrShortWrite
} else if err != nil {
return err
}
if err = f.Sync(); err != nil {
return err
}
return f.Close()
}
// Waits for a random time between two durations and sends the current time on
// the returned channel.
func afterBetween(min time.Duration, max time.Duration) <-chan time.Time {
rand := rand.New(rand.NewSource(time.Now().UnixNano()))
d, delta := min, (max - min)
if delta > 0 {
d += time.Duration(rand.Int63n(int64(delta)))
}
return time.After(d)
}
// TODO(xiangli): Remove assertions when we reach version 1.0
// _assert will panic with a given formatted message if the given condition is false.
func _assert(condition bool, msg string, v ...interface{}) {
if !condition {
panic(fmt.Sprintf("assertion failed: "+msg, v...))
}
}

View File

@ -1,13 +0,0 @@
package raft
/*
import (
"testing"
"time"
)
func TestGC(t *testing.T) {
<-time.After(500 * time.Millisecond)
panic("Oh god no!")
}
*/

295
cmd/influxd/config.go Normal file
View File

@ -0,0 +1,295 @@
package main
import (
"fmt"
"os"
"strconv"
"time"
"github.com/BurntSushi/toml"
)
const (
// DefaultPointBatchSize represents the number of points to batch together.
DefaultPointBatchSize = 100
// DefaultPointBatchSize represents the number of writes to batch together.
DefaultWriteBatchSize = 10 * 1024 * 1024 // 10MB
// DefaultConcurrentShardQueryLimit represents the number of shards that
// can be queried concurrently at one time.
DefaultConcurrentShardQueryLimit = 10
// DefaultAPIReadTimeout represents the amount time before an API request
// times out.
DefaultAPIReadTimeout = 5 * time.Second
)
// Config represents the configuration format for the influxd binary.
type Config struct {
Hostname string `toml:"hostname"`
BindAddress string `toml:"bind-address"`
ReportingDisabled bool `toml:"reporting-disabled"`
Admin struct {
Port int `toml:"port"`
Assets string `toml:"assets"`
} `toml:"admin"`
HTTPAPI struct {
Port int `toml:"port"`
SSLPort int `toml:"ssl-port"`
SSLCertPath string `toml:"ssl-cert"`
ReadTimeout Duration `toml:"read-timeout"`
} `toml:"api"`
InputPlugins struct {
Graphite struct {
Enabled bool `toml:"enabled"`
Port int `toml:"port"`
Database string `toml:"database"`
UDPEnabled bool `toml:"udp_enabled"`
} `toml:"graphite"`
UDPInput struct {
Enabled bool `toml:"enabled"`
Port int `toml:"port"`
Database string `toml:"database"`
} `toml:"udp"`
UDPServersInput []struct {
Enabled bool `toml:"enabled"`
Port int `toml:"port"`
Database string `toml:"database"`
} `toml:"udp_servers"`
} `toml:"input_plugins"`
Raft struct {
Port int `toml:"port"`
Dir string `toml:"dir"`
Timeout Duration `toml:"election-timeout"`
} `toml:"raft"`
Storage struct {
Dir string `toml:"dir"`
DefaultEngine string `toml:"default-engine"`
WriteBufferSize int `toml:"write-buffer-size"`
MaxOpenShards int `toml:"max-open-shards"`
PointBatchSize int `toml:"point-batch-size"`
WriteBatchSize int `toml:"write-batch-size"`
Engines map[string]toml.Primitive `toml:"engines"`
RetentionSweepPeriod Duration `toml:"retention-sweep-period"`
} `toml:"storage"`
Cluster struct {
SeedServers []string `toml:"seed-servers"`
ProtobufPort int `toml:"protobuf_port"`
ProtobufTimeout Duration `toml:"protobuf_timeout"`
ProtobufHeartbeatInterval Duration `toml:"protobuf_heartbeat"`
MinBackoff Duration `toml:"protobuf_min_backoff"`
MaxBackoff Duration `toml:"protobuf_max_backoff"`
WriteBufferSize int `toml:"write-buffer-size"`
ConcurrentShardQueryLimit int `toml:"concurrent-shard-query-limit"`
MaxResponseBufferSize int `toml:"max-response-buffer-size"`
} `toml:"cluster"`
Logging struct {
File string `toml:"file"`
Level string `toml:"level"`
} `toml:"logging"`
LevelDB struct {
MaxOpenFiles int `toml:"max-open-files"`
LruCacheSize Size `toml:"lru-cache-size"`
// Global configuration, use storage config values not set.
MaxOpenShards int `toml:"max-open-shards"`
PointBatchSize int `toml:"point-batch-size"`
WriteBatchSize int `toml:"write-batch-size"`
} `toml:"leveldb"`
}
// NewConfig returns an instance of Config with reasonable defaults.
func NewConfig() *Config {
c := &Config{}
c.Storage.DefaultEngine = "leveldb"
c.Storage.RetentionSweepPeriod = Duration(10 * time.Minute)
c.Cluster.ConcurrentShardQueryLimit = DefaultConcurrentShardQueryLimit
c.Raft.Timeout = Duration(1 * time.Second)
c.HTTPAPI.ReadTimeout = Duration(DefaultAPIReadTimeout)
c.Cluster.MinBackoff = Duration(1 * time.Second)
c.Cluster.MaxBackoff = Duration(10 * time.Second)
c.Cluster.ProtobufHeartbeatInterval = Duration(10 * time.Millisecond)
c.Storage.WriteBufferSize = 1000
c.Cluster.WriteBufferSize = 1000
c.Cluster.MaxResponseBufferSize = 100
// Detect hostname (or set to localhost).
if c.Hostname, _ = os.Hostname(); c.Hostname == "" {
c.Hostname = "localhost"
}
// FIX(benbjohnson): Append where the udp servers are actually used.
// config.UDPServers = append(config.UDPServers, UDPInputConfig{
// Enabled: tomlConfiguration.InputPlugins.UDPInput.Enabled,
// Database: tomlConfiguration.InputPlugins.UDPInput.Database,
// Port: tomlConfiguration.InputPlugins.UDPInput.Port,
// })
return c
}
// PointBatchSize returns the storage point batch size, if set.
// If not set, the LevelDB point batch size is returned.
// If that is not set then the default point batch size is returned.
func (c *Config) PointBatchSize() int {
if c.Storage.PointBatchSize != 0 {
return c.Storage.PointBatchSize
} else if c.LevelDB.PointBatchSize != 0 {
return c.LevelDB.PointBatchSize
}
return DefaultPointBatchSize
}
// WriteBatchSize returns the storage write batch size, if set.
// If not set, the LevelDB write batch size is returned.
// If that is not set then the default write batch size is returned.
func (c *Config) WriteBatchSize() int {
if c.Storage.WriteBatchSize != 0 {
return c.Storage.WriteBatchSize
} else if c.LevelDB.WriteBatchSize != 0 {
return c.LevelDB.WriteBatchSize
}
return DefaultWriteBatchSize
}
// MaxOpenShards returns the maximum number of shards to keep open at once.
func (c *Config) MaxOpenShards() int {
if c.Storage.MaxOpenShards != 0 {
return c.Storage.MaxOpenShards
}
return c.LevelDB.MaxOpenShards
}
// Size represents a TOML parseable file size.
// Users can specify size using "m" for megabytes and "g" for gigabytes.
type Size int
// UnmarshalText parses a byte size from text.
func (s *Size) UnmarshalText(text []byte) error {
// Parse numeric portion of value.
length := len(string(text))
size, err := strconv.ParseInt(string(text[:length-1]), 10, 64)
if err != nil {
return err
}
// Parse unit of measure ("m", "g", etc).
switch suffix := text[len(text)-1]; suffix {
case 'm':
size *= 1 << 20 // MB
case 'g':
size *= 1 << 30 // GB
default:
return fmt.Errorf("unknown size suffix: %c", suffix)
}
// Check for overflow.
if size > maxInt {
return fmt.Errorf("size %d cannot be represented by an int", size)
}
*s = Size(size)
return nil
}
// Duration is a TOML wrapper type for time.Duration.
type Duration time.Duration
// UnmarshalText parses a TOML value into a duration value.
func (d *Duration) UnmarshalText(text []byte) error {
// Ignore if there is no value set.
if len(text) == 0 {
return nil
}
// Otherwise parse as a duration formatted string.
duration, err := time.ParseDuration(string(text))
if err != nil {
return err
}
// Set duration and return.
*d = Duration(duration)
return nil
}
// ParseConfigFile parses a configuration file at a given path.
func ParseConfigFile(path string) (*Config, error) {
c := NewConfig()
if _, err := toml.DecodeFile(path, &c); err != nil {
return nil, err
}
return c, nil
}
// ParseConfig parses a configuration string into a config object.
func ParseConfig(s string) (*Config, error) {
c := NewConfig()
if _, err := toml.Decode(s, &c); err != nil {
return nil, err
}
return c, nil
}
/*
func (c *Config) AdminHTTPPortString() string {
if c.AdminHTTPPort <= 0 {
return ""
}
return fmt.Sprintf("%s:%d", c.BindAddress, c.AdminHTTPPort)
}
func (c *Config) ApiHTTPPortString() string {
if c.HTTPAPI.Port <= 0 {
return ""
}
return fmt.Sprintf("%s:%d", c.BindAddress, c.HTTPAPI.Port)
}
func (c *Config) APIHTTPSPortString() string {
return fmt.Sprintf("%s:%d", c.BindAddress, c.APIHTTPSPort)
}
func (c *Config) GraphitePortString() string {
if c.GraphitePort <= 0 {
return ""
}
return fmt.Sprintf("%s:%d", c.BindAddress, c.GraphitePort)
}
func (c *Config) UDPInputPortString(port int) string {
if port <= 0 {
return ""
}
return fmt.Sprintf("%s:%d", c.BindAddress, port)
}
func (c *Config) ProtobufConnectionString() string {
return fmt.Sprintf("%s:%d", c.Hostname, c.ProtobufPort)
}
func (c *Config) RaftConnectionString() string {
return fmt.Sprintf("http://%s:%d", c.Hostname, c.RaftServerPort)
}
func (c *Config) ProtobufListenString() string {
return fmt.Sprintf("%s:%d", c.BindAddress, c.ProtobufPort)
}
func (c *Config) RaftListenString() string {
return fmt.Sprintf("%s:%d", c.BindAddress, c.RaftServerPort)
}
*/
// maxInt is the largest integer representable by a word (architeture dependent).
const maxInt = int64(^uint(0) >> 1)

View File

@ -1,9 +1,119 @@
package main_test
import (
"reflect"
"testing"
"time"
"github.com/influxdb/influxdb/cmd/influxd"
)
// Ensure that megabyte sizes can be parsed.
func TestSize_UnmarshalText_MB(t *testing.T) {
var s main.Size
if err := s.UnmarshalText([]byte("200m")); err != nil {
t.Fatalf("unexpected error: %s", err)
} else if s != 200*(1<<20) {
t.Fatalf("unexpected size: %d", s)
}
}
// Ensure that gigabyte sizes can be parsed.
func TestSize_UnmarshalText_GB(t *testing.T) {
if typ := reflect.TypeOf(0); typ.Size() != 8 {
t.Skip("large gigabyte parsing on 64-bit arch only")
}
var s main.Size
if err := s.UnmarshalText([]byte("10g")); err != nil {
t.Fatalf("unexpected error: %s", err)
} else if s != 10*(1<<30) {
t.Fatalf("unexpected size: %d", s)
}
}
// Ensure that a TOML configuration file can be parsed into a Config.
func TestParseConfig(t *testing.T) {
c, err := main.ParseConfig(testFile)
if err != nil {
t.Fatalf("unexpected error: %s", err)
} else if c.Hostname != "myserver.com" {
t.Fatalf("hostname mismatch: %v", c.Hostname)
}
if c.Logging.File != "influxdb.log" {
t.Fatalf("logging file mismatch: %v", c.Logging.File)
} else if c.Logging.Level != "info" {
t.Fatalf("logging level mismatch: %v", c.Logging.Level)
}
if c.Admin.Port != 8083 {
t.Fatalf("admin port mismatch: %v", c.Admin.Port)
} else if c.Admin.Assets != "./admin" {
t.Fatalf("admin assets mismatch: %v", c.Admin.Assets)
}
if c.HTTPAPI.Port != 0 {
t.Fatalf("http api port mismatch: %v", c.HTTPAPI.Port)
} else if c.HTTPAPI.SSLPort != 8087 {
t.Fatalf("http api ssl port mismatch: %v", c.HTTPAPI.SSLPort)
} else if c.HTTPAPI.SSLCertPath != "../cert.pem" {
t.Fatalf("http api ssl cert path mismatch: %v", c.HTTPAPI.SSLCertPath)
}
if c.InputPlugins.Graphite.Enabled != false {
t.Fatalf("graphite enabled mismatch: %v", c.InputPlugins.Graphite.Enabled)
} else if c.InputPlugins.Graphite.Port != 2003 {
t.Fatalf("graphite port mismatch: %v", c.InputPlugins.Graphite.Enabled)
} else if c.InputPlugins.Graphite.Database != "" {
t.Fatalf("graphite database mismatch: %v", c.InputPlugins.Graphite.Database)
}
if c.Raft.Port != 8090 {
t.Fatalf("raft port mismatch: %v", c.Raft.Port)
} else if c.Raft.Dir != "/tmp/influxdb/development/raft" {
t.Fatalf("raft dir mismatch: %v", c.Raft.Dir)
} else if time.Duration(c.Raft.Timeout) != time.Second {
t.Fatalf("raft duration mismatch: %v", c.Raft.Timeout)
}
if c.Storage.Dir != "/tmp/influxdb/development/db" {
t.Fatalf("data dir mismatch: %v", c.Storage.Dir)
}
if c.Cluster.ProtobufPort != 8099 {
t.Fatalf("protobuf port mismatch: %v", c.Cluster.ProtobufPort)
} else if time.Duration(c.Cluster.ProtobufTimeout) != 2*time.Second {
t.Fatalf("protobuf timeout mismatch: %v", c.Cluster.ProtobufTimeout)
} else if time.Duration(c.Cluster.ProtobufHeartbeatInterval) != 200*time.Millisecond {
t.Fatalf("protobuf heartbeat interval mismatch: %v", c.Cluster.ProtobufHeartbeatInterval)
} else if time.Duration(c.Cluster.MinBackoff) != 100*time.Millisecond {
t.Fatalf("min backoff mismatch: %v", c.Cluster.MinBackoff)
} else if time.Duration(c.Cluster.MaxBackoff) != 1*time.Second {
t.Fatalf("max backoff mismatch: %v", c.Cluster.MaxBackoff)
} else if !reflect.DeepEqual(c.Cluster.SeedServers, []string{"hosta:8090", "hostb:8090"}) {
t.Fatalf("seed servers mismatch: %+v", c.Cluster.SeedServers)
} else if c.Cluster.MaxResponseBufferSize != 5 {
t.Fatalf("max response buffer size mismatch: %v", c.Cluster.MaxResponseBufferSize)
}
// TODO: UDP Servers testing.
/*
c.Assert(config.UdpServers, HasLen, 1)
c.Assert(config.UdpServers[0].Enabled, Equals, true)
c.Assert(config.UdpServers[0].Port, Equals, 4444)
c.Assert(config.UdpServers[0].Database, Equals, "test")
*/
}
// Testing configuration file.
const testFile = `
# Welcome to the InfluxDB configuration file.
# If hostname (on the OS) doesn't return a name that can be resolved by the other
# systems in the cluster, you'll have to set the hostname to an IP or something
# that can be resolved here.
# hostname = ""
hostname = "myserver.com"
[logging]
# logging level can be one of "debug", "info", "warn" or "error"
@ -104,6 +214,7 @@ concurrent-shard-query-limit = 10
# the process
# max-open-files = 40
lru-cache-size = "200m"
# The default setting on this is 0, which means unlimited. Set this to
# something if you want to limit the max number of open
# files. max-open-files is per shard so this * that will be max.
@ -112,17 +223,4 @@ lru-cache-size = "200m"
# The default setting is 100. This option tells how many points will be fetched from LevelDb before
# they get flushed into backend.
point-batch-size = 50
[wal]
dir = "/tmp/influxdb/development/wal"
# flush-after = 0 # the number of writes after which wal will be flushed, 0 for flushing on every write
# bookmark-after = 0 # the number of writes after which a bookmark will be created
# the number of writes after which an index entry is created pointing
# to the offset of the first request, default to 1k
# index-after = 0
# the number of requests per one log file, if new requests came in a
# new log file will be created
# requests-per-logfile = 10000
`

View File

@ -18,59 +18,19 @@ import (
"github.com/jmhodges/levigo"
)
func setupLogging(loggingLevel, logFile string) {
level := log.DEBUG
switch loggingLevel {
case "info":
level = log.INFO
case "warn":
level = log.WARNING
case "error":
level = log.ERROR
}
log.Global = make(map[string]*log.Filter)
facility, ok := GetSysLogFacility(logFile)
if ok {
flw, err := NewSysLogWriter(facility)
if err != nil {
fmt.Fprintf(os.Stderr, "NewSysLogWriter: %s\n", err.Error())
return
}
log.AddFilter("syslog", level, flw)
} else if logFile == "stdout" {
flw := log.NewConsoleLogWriter()
log.AddFilter("stdout", level, flw)
} else {
logFileDir := filepath.Dir(logFile)
os.MkdirAll(logFileDir, 0744)
flw := log.NewFileLogWriter(logFile, false)
log.AddFilter("file", level, flw)
flw.SetFormat("[%D %T] [%L] (%S) %M")
flw.SetRotate(true)
flw.SetRotateSize(0)
flw.SetRotateLines(0)
flw.SetRotateDaily(true)
}
log.Info("Redirectoring logging to %s", logFile)
}
func main() {
fileName := flag.String("config", "config.sample.toml", "Config file")
wantsVersion := flag.Bool("v", false, "Get version number")
resetRootPassword := flag.Bool("reset-root", false, "Reset root password")
hostname := flag.String("hostname", "", "Override the hostname, the `hostname` config option will be overridden")
raftPort := flag.Int("raft-port", 0, "Override the raft port, the `raft.port` config option will be overridden")
protobufPort := flag.Int("protobuf-port", 0, "Override the protobuf port, the `protobuf_port` config option will be overridden")
pidFile := flag.String("pidfile", "", "the pid file")
repairLeveldb := flag.Bool("repair-ldb", false, "set to true to repair the leveldb files")
stdout := flag.Bool("stdout", false, "Log to stdout overriding the configuration")
syslog := flag.String("syslog", "", "Log to syslog facility overriding the configuration")
var (
fileName = flag.String("config", "config.sample.toml", "Config file")
wantsVersion = flag.Bool("v", false, "Get version number")
resetRootPassword = flag.Bool("reset-root", false, "Reset root password")
hostname = flag.String("hostname", "", "Override the hostname, the `hostname` config option will be overridden")
raftPort = flag.Int("raft-port", 0, "Override the raft port, the `raft.port` config option will be overridden")
protobufPort = flag.Int("protobuf-port", 0, "Override the protobuf port, the `protobuf_port` config option will be overridden")
pidFile = flag.String("pidfile", "", "the pid file")
repairLeveldb = flag.Bool("repair-ldb", false, "set to true to repair the leveldb files")
stdout = flag.Bool("stdout", false, "Log to stdout overriding the configuration")
syslog = flag.String("syslog", "", "Log to syslog facility overriding the configuration")
)
runtime.GOMAXPROCS(runtime.NumCPU())
flag.Parse()
@ -181,3 +141,48 @@ func main() {
log.Error("ListenAndServe failed: ", err)
}
}
func setupLogging(loggingLevel, logFile string) {
level := log.DEBUG
switch loggingLevel {
case "info":
level = log.INFO
case "warn":
level = log.WARNING
case "error":
level = log.ERROR
}
log.Global = make(map[string]*log.Filter)
facility, ok := GetSysLogFacility(logFile)
if ok {
flw, err := NewSysLogWriter(facility)
if err != nil {
fmt.Fprintf(os.Stderr, "NewSysLogWriter: %s\n", err.Error())
return
}
log.AddFilter("syslog", level, flw)
} else if logFile == "stdout" {
flw := log.NewConsoleLogWriter()
log.AddFilter("stdout", level, flw)
} else {
logFileDir := filepath.Dir(logFile)
os.MkdirAll(logFileDir, 0744)
flw := log.NewFileLogWriter(logFile, false)
log.AddFilter("file", level, flw)
flw.SetFormat("[%D %T] [%L] (%S) %M")
flw.SetRotate(true)
flw.SetRotateSize(0)
flw.SetRotateLines(0)
flw.SetRotateDaily(true)
}
log.Info("Redirectoring logging to %s", logFile)
}
type Stopper interface {
Stop()
}

View File

@ -11,12 +11,12 @@ import (
log "code.google.com/p/log4go"
)
func startProfiler(stoppable Stoppable) error {
go waitForSignals(stoppable)
func startProfiler(stopper Stopper) error {
go waitForSignals(stopper)
return nil
}
func waitForSignals(stoppable Stoppable) {
func waitForSignals(stopper Stopper) {
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGTERM, syscall.SIGINT)
for {
@ -24,7 +24,7 @@ func waitForSignals(stoppable Stoppable) {
log.Info("Received signal: %s", sig.String())
switch sig {
case syscall.SIGINT, syscall.SIGTERM:
stoppable.Stop()
stopper.Stop()
time.Sleep(time.Second)
os.Exit(0)
}

View File

@ -1,5 +1,4 @@
// build this file if the profile tag is specified and we're running
// on linux
// build this file if the profile tag is specified and we're running on linux
// +build linux,profile
@ -29,7 +28,7 @@ func init() {
profileFilename = flag.String("profile", "", "filename prefix where cpu and memory profile data will be written")
}
func waitForSignals(stoppable Stoppable, filename string, stopped <-chan bool) {
func waitForSignals(stopper Stopper, filename string, stopped <-chan bool) {
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGTERM, syscall.SIGINT)
outer:
@ -50,7 +49,7 @@ outer:
f.Close()
stopCHeapProfiler()
// stopCCpuProfiler()
stoppable.Stop()
stopper.Stop()
break outer
// make sure everything stopped before exiting
}
@ -61,7 +60,7 @@ outer:
os.Exit(0)
}
func startProfiler(stoppable Stoppable) error {
func startProfiler(stopper Stopper) error {
if profileFilename == nil || *profileFilename == "" {
log.Info("Not starting profiling since the profile prefix is not set")
return nil
@ -80,7 +79,7 @@ func startProfiler(stoppable Stoppable) error {
runtime.SetCPUProfileRate(500)
stopped := make(chan bool)
go waitForSignals(stoppable, *profileFilename, stopped)
go waitForSignals(stopper, *profileFilename, stopped)
go func() {
for {

View File

@ -1,425 +0,0 @@
package configuration
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strconv"
"time"
log "code.google.com/p/log4go"
"github.com/BurntSushi/toml"
)
type Size int
const (
ONE_MEGABYTE int64 = 1024 * 1024
ONE_GIGABYTE = 1024 * ONE_MEGABYTE
// Maximum integer representable by a word (32bit or 64bit depending
// on the architecture)
MAX_INT = int64(^uint(0) >> 1)
)
func (d *Size) UnmarshalText(text []byte) error {
str := string(text)
length := len(str)
size, err := strconv.ParseInt(string(text[:length-1]), 10, 64)
if err != nil {
return err
}
switch suffix := text[len(text)-1]; suffix {
case 'm':
size *= ONE_MEGABYTE
case 'g':
size *= ONE_GIGABYTE
default:
return fmt.Errorf("Unknown size suffix %c", suffix)
}
if size > MAX_INT {
return fmt.Errorf("Size %d cannot be represented by an int", size)
}
*d = Size(size)
return nil
}
type duration struct {
time.Duration
}
func (d *duration) UnmarshalText(text []byte) error {
if len(text) == 0 {
return nil
}
var err error
d.Duration, err = time.ParseDuration(string(text))
return err
}
type AdminConfig struct {
Port int
Assets string
}
type ApiConfig struct {
SslPort int `toml:"ssl-port"`
SslCertPath string `toml:"ssl-cert"`
Port int
ReadTimeout duration `toml:"read-timeout"`
}
type GraphiteConfig struct {
Enabled bool
Port int
Database string
UdpEnabled bool `toml:"udp_enabled"`
}
type UdpInputConfig struct {
Enabled bool
Port int
Database string
}
type RaftConfig struct {
Port int
Dir string
Timeout duration `toml:"election-timeout"`
}
type StorageConfig struct {
Dir string
DefaultEngine string `toml:"default-engine"`
WriteBufferSize int `toml:"write-buffer-size"`
MaxOpenShards int `toml:"max-open-shards"`
PointBatchSize int `toml:"point-batch-size"`
WriteBatchSize int `toml:"write-batch-size"`
Engines map[string]toml.Primitive
RetentionSweepPeriod duration `toml:"retention-sweep-period"`
}
type ClusterConfig struct {
SeedServers []string `toml:"seed-servers"`
ProtobufPort int `toml:"protobuf_port"`
ProtobufTimeout duration `toml:"protobuf_timeout"`
ProtobufHeartbeatInterval duration `toml:"protobuf_heartbeat"`
MinBackoff duration `toml:"protobuf_min_backoff"`
MaxBackoff duration `toml:"protobuf_max_backoff"`
WriteBufferSize int `toml:"write-buffer-size"`
ConcurrentShardQueryLimit int `toml:"concurrent-shard-query-limit"`
MaxResponseBufferSize int `toml:"max-response-buffer-size"`
}
type LevelDbConfiguration struct {
MaxOpenFiles int `toml:"max-open-files"`
LruCacheSize Size `toml:"lru-cache-size"`
// global configuration, use these values if the values in
// StorageConfig aren't set
MaxOpenShards int `toml:"max-open-shards"`
PointBatchSize int `toml:"point-batch-size"`
WriteBatchSize int `toml:"write-batch-size"`
}
type LoggingConfig struct {
File string
Level string
}
type InputPlugins struct {
Graphite GraphiteConfig `toml:"graphite"`
UdpInput UdpInputConfig `toml:"udp"`
UdpServersInput []UdpInputConfig `toml:"udp_servers"`
}
type TomlConfiguration struct {
Admin AdminConfig
HttpApi ApiConfig `toml:"api"`
InputPlugins InputPlugins `toml:"input_plugins"`
Raft RaftConfig
Storage StorageConfig
Cluster ClusterConfig
Logging LoggingConfig
Hostname string
BindAddress string `toml:"bind-address"`
ReportingDisabled bool `toml:"reporting-disabled"`
LevelDb LevelDbConfiguration
}
type Configuration struct {
AdminHttpPort int
AdminAssetsDir string
ApiHttpSslPort int
ApiHttpCertPath string
ApiHttpPort int
ApiReadTimeout time.Duration
GraphiteEnabled bool
GraphitePort int
GraphiteDatabase string
GraphiteUdpEnabled bool
UdpServers []UdpInputConfig
StorageDefaultEngine string
StorageMaxOpenShards int
StoragePointBatchSize int
StorageWriteBatchSize int
StorageEngineConfigs map[string]toml.Primitive
StorageRetentionSweepPeriod duration
// TODO: this is for backward compatability only
LevelDbMaxOpenFiles int
LevelDbLruCacheSize int
RaftServerPort int
RaftTimeout duration
SeedServers []string
DataDir string
RaftDir string
ProtobufPort int
ProtobufTimeout duration
ProtobufHeartbeatInterval duration
ProtobufMinBackoff duration
ProtobufMaxBackoff duration
Hostname string
LogFile string
LogLevel string
BindAddress string
LocalStoreWriteBufferSize int
PerServerWriteBufferSize int
ClusterMaxResponseBufferSize int
ConcurrentShardQueryLimit int
ReportingDisabled bool
Version string
InfluxDBVersion string
}
func LoadConfiguration(fileName string) (*Configuration, error) {
log.Info("Loading configuration file %s", fileName)
config, err := parseTomlConfiguration(fileName)
if err != nil {
fmt.Println("Couldn't parse configuration file: " + fileName)
fmt.Println(err)
return nil, err
}
return config, nil
}
func parseTomlConfiguration(filename string) (*Configuration, error) {
body, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
tomlConfiguration := &TomlConfiguration{}
_, err = toml.Decode(string(body), tomlConfiguration)
if err != nil {
return nil, err
}
// if it wasn't set, set it to 100
if tomlConfiguration.Storage.PointBatchSize == 0 {
if s := tomlConfiguration.LevelDb.PointBatchSize; s != 0 {
tomlConfiguration.Storage.PointBatchSize = s
} else {
tomlConfiguration.Storage.PointBatchSize = 100
}
}
// if it wasn't set, set it to 10M
if tomlConfiguration.Storage.WriteBatchSize == 0 {
if s := tomlConfiguration.LevelDb.WriteBatchSize; s != 0 {
tomlConfiguration.Storage.WriteBatchSize = s
} else {
tomlConfiguration.Storage.WriteBatchSize = 10 * 1024 * 1024
}
}
if tomlConfiguration.Storage.MaxOpenShards == 0 {
tomlConfiguration.Storage.MaxOpenShards = tomlConfiguration.LevelDb.MaxOpenShards
}
if tomlConfiguration.Storage.DefaultEngine == "" {
tomlConfiguration.Storage.DefaultEngine = "leveldb"
}
if tomlConfiguration.Storage.RetentionSweepPeriod.Duration == 0 {
tomlConfiguration.Storage.RetentionSweepPeriod = duration{10 * time.Minute}
}
defaultConcurrentShardQueryLimit := 10
if tomlConfiguration.Cluster.ConcurrentShardQueryLimit != 0 {
defaultConcurrentShardQueryLimit = tomlConfiguration.Cluster.ConcurrentShardQueryLimit
}
if tomlConfiguration.Raft.Timeout.Duration == 0 {
tomlConfiguration.Raft.Timeout = duration{time.Second}
}
apiReadTimeout := tomlConfiguration.HttpApi.ReadTimeout.Duration
if apiReadTimeout == 0 {
apiReadTimeout = 5 * time.Second
}
if tomlConfiguration.Cluster.MinBackoff.Duration == 0 {
tomlConfiguration.Cluster.MinBackoff = duration{time.Second}
}
if tomlConfiguration.Cluster.MaxBackoff.Duration == 0 {
tomlConfiguration.Cluster.MaxBackoff = duration{10 * time.Second}
}
if tomlConfiguration.Cluster.ProtobufHeartbeatInterval.Duration == 0 {
tomlConfiguration.Cluster.ProtobufHeartbeatInterval = duration{10 * time.Millisecond}
}
config := &Configuration{
AdminHttpPort: tomlConfiguration.Admin.Port,
AdminAssetsDir: tomlConfiguration.Admin.Assets,
ApiHttpPort: tomlConfiguration.HttpApi.Port,
ApiHttpCertPath: tomlConfiguration.HttpApi.SslCertPath,
ApiHttpSslPort: tomlConfiguration.HttpApi.SslPort,
ApiReadTimeout: apiReadTimeout,
GraphiteEnabled: tomlConfiguration.InputPlugins.Graphite.Enabled,
GraphitePort: tomlConfiguration.InputPlugins.Graphite.Port,
GraphiteDatabase: tomlConfiguration.InputPlugins.Graphite.Database,
GraphiteUdpEnabled: tomlConfiguration.InputPlugins.Graphite.UdpEnabled,
UdpServers: tomlConfiguration.InputPlugins.UdpServersInput,
// storage configuration
StorageDefaultEngine: tomlConfiguration.Storage.DefaultEngine,
StorageMaxOpenShards: tomlConfiguration.Storage.MaxOpenShards,
StoragePointBatchSize: tomlConfiguration.Storage.PointBatchSize,
StorageWriteBatchSize: tomlConfiguration.Storage.WriteBatchSize,
DataDir: tomlConfiguration.Storage.Dir,
LocalStoreWriteBufferSize: tomlConfiguration.Storage.WriteBufferSize,
StorageEngineConfigs: tomlConfiguration.Storage.Engines,
StorageRetentionSweepPeriod: tomlConfiguration.Storage.RetentionSweepPeriod,
LevelDbMaxOpenFiles: tomlConfiguration.LevelDb.MaxOpenFiles,
LevelDbLruCacheSize: int(tomlConfiguration.LevelDb.LruCacheSize),
RaftServerPort: tomlConfiguration.Raft.Port,
RaftTimeout: tomlConfiguration.Raft.Timeout,
RaftDir: tomlConfiguration.Raft.Dir,
ProtobufPort: tomlConfiguration.Cluster.ProtobufPort,
ProtobufTimeout: tomlConfiguration.Cluster.ProtobufTimeout,
ProtobufHeartbeatInterval: tomlConfiguration.Cluster.ProtobufHeartbeatInterval,
ProtobufMinBackoff: tomlConfiguration.Cluster.MinBackoff,
ProtobufMaxBackoff: tomlConfiguration.Cluster.MaxBackoff,
SeedServers: tomlConfiguration.Cluster.SeedServers,
LogFile: tomlConfiguration.Logging.File,
LogLevel: tomlConfiguration.Logging.Level,
Hostname: tomlConfiguration.Hostname,
BindAddress: tomlConfiguration.BindAddress,
ReportingDisabled: tomlConfiguration.ReportingDisabled,
PerServerWriteBufferSize: tomlConfiguration.Cluster.WriteBufferSize,
ClusterMaxResponseBufferSize: tomlConfiguration.Cluster.MaxResponseBufferSize,
ConcurrentShardQueryLimit: defaultConcurrentShardQueryLimit,
}
config.UdpServers = append(config.UdpServers, UdpInputConfig{
Enabled: tomlConfiguration.InputPlugins.UdpInput.Enabled,
Database: tomlConfiguration.InputPlugins.UdpInput.Database,
Port: tomlConfiguration.InputPlugins.UdpInput.Port,
})
if config.LocalStoreWriteBufferSize == 0 {
config.LocalStoreWriteBufferSize = 1000
}
if config.PerServerWriteBufferSize == 0 {
config.PerServerWriteBufferSize = 1000
}
if config.ClusterMaxResponseBufferSize == 0 {
config.ClusterMaxResponseBufferSize = 100
}
return config, nil
}
func parseJsonConfiguration(fileName string) (*Configuration, error) {
log.Info("Loading Config from " + fileName)
config := &Configuration{}
data, err := ioutil.ReadFile(fileName)
if err == nil {
err = json.Unmarshal(data, config)
if err != nil {
return nil, err
}
} else {
log.Error("Couldn't load configuration file: " + fileName)
panic(err)
}
return config, nil
}
func (self *Configuration) AdminHttpPortString() string {
if self.AdminHttpPort <= 0 {
return ""
}
return fmt.Sprintf("%s:%d", self.BindAddress, self.AdminHttpPort)
}
func (self *Configuration) ApiHttpPortString() string {
if self.ApiHttpPort <= 0 {
return ""
}
return fmt.Sprintf("%s:%d", self.BindAddress, self.ApiHttpPort)
}
func (self *Configuration) ApiHttpSslPortString() string {
return fmt.Sprintf("%s:%d", self.BindAddress, self.ApiHttpSslPort)
}
func (self *Configuration) GraphitePortString() string {
if self.GraphitePort <= 0 {
return ""
}
return fmt.Sprintf("%s:%d", self.BindAddress, self.GraphitePort)
}
func (self *Configuration) UdpInputPortString(port int) string {
if port <= 0 {
return ""
}
return fmt.Sprintf("%s:%d", self.BindAddress, port)
}
func (self *Configuration) HostnameOrDetect() string {
if self.Hostname != "" {
return self.Hostname
} else {
n, err := os.Hostname()
if err == nil {
return n
} else {
return "localhost"
}
}
}
func (self *Configuration) ProtobufConnectionString() string {
return fmt.Sprintf("%s:%d", self.HostnameOrDetect(), self.ProtobufPort)
}
func (self *Configuration) RaftConnectionString() string {
return fmt.Sprintf("http://%s:%d", self.HostnameOrDetect(), self.RaftServerPort)
}
func (self *Configuration) ProtobufListenString() string {
return fmt.Sprintf("%s:%d", self.BindAddress, self.ProtobufPort)
}
func (self *Configuration) RaftListenString() string {
return fmt.Sprintf("%s:%d", self.BindAddress, self.RaftServerPort)
}

View File

@ -1,75 +0,0 @@
package configuration
import (
"reflect"
"testing"
"time"
. "launchpad.net/gocheck"
)
// Hook up gocheck into the gotest runner.
func Test(t *testing.T) {
TestingT(t)
}
type LoadConfigurationSuite struct{}
var _ = Suite(&LoadConfigurationSuite{})
func (self *LoadConfigurationSuite) TestConfig(c *C) {
config, err := LoadConfiguration("config.toml")
c.Assert(err, Equals, nil)
c.Assert(config.Hostname, Equals, "")
c.Assert(config.LogFile, Equals, "influxdb.log")
c.Assert(config.LogLevel, Equals, "info")
c.Assert(config.AdminAssetsDir, Equals, "./admin")
c.Assert(config.AdminHttpPort, Equals, 8083)
c.Assert(config.ApiHttpPort, Equals, 0)
c.Assert(config.ApiHttpSslPort, Equals, 8087)
c.Assert(config.ApiHttpCertPath, Equals, "../cert.pem")
c.Assert(config.ApiHttpPortString(), Equals, "")
c.Assert(config.GraphiteEnabled, Equals, false)
c.Assert(config.GraphitePort, Equals, 2003)
c.Assert(config.GraphiteDatabase, Equals, "")
c.Assert(config.UdpServers, HasLen, 1)
c.Assert(config.UdpServers[0].Enabled, Equals, true)
c.Assert(config.UdpServers[0].Port, Equals, 4444)
c.Assert(config.UdpServers[0].Database, Equals, "test")
c.Assert(config.RaftDir, Equals, "/tmp/influxdb/development/raft")
c.Assert(config.RaftServerPort, Equals, 8090)
c.Assert(config.RaftTimeout.Duration, Equals, time.Second)
c.Assert(config.DataDir, Equals, "/tmp/influxdb/development/db")
c.Assert(config.ProtobufPort, Equals, 8099)
c.Assert(config.ProtobufHeartbeatInterval.Duration, Equals, 200*time.Millisecond)
c.Assert(config.ProtobufMinBackoff.Duration, Equals, 100*time.Millisecond)
c.Assert(config.ProtobufMaxBackoff.Duration, Equals, time.Second)
c.Assert(config.ProtobufTimeout.Duration, Equals, 2*time.Second)
c.Assert(config.SeedServers, DeepEquals, []string{"hosta:8090", "hostb:8090"})
c.Assert(config.WalDir, Equals, "/tmp/influxdb/development/wal")
c.Assert(config.WalFlushAfterRequests, Equals, 0)
c.Assert(config.WalBookmarkAfterRequests, Equals, 0)
c.Assert(config.WalIndexAfterRequests, Equals, 1000)
c.Assert(config.WalRequestsPerLogFile, Equals, 10000)
c.Assert(config.ClusterMaxResponseBufferSize, Equals, 5)
}
func (self *LoadConfigurationSuite) TestSizeParsing(c *C) {
var s Size
c.Assert(s.UnmarshalText([]byte("200m")), IsNil)
c.Assert(int64(s), Equals, 200*ONE_MEGABYTE)
if t := reflect.TypeOf(0); t.Size() > 4 {
c.Assert(s.UnmarshalText([]byte("10g")), IsNil)
c.Assert(int64(s), Equals, 10*ONE_GIGABYTE)
}
}

View File

@ -1,5 +0,0 @@
package main
type Stoppable interface {
Stop()
}