memberlist: vendor v0.1.6 to pull in new state: stateLeft (#7184)

This commit is contained in:
Hans Hasselberg 2020-02-03 11:02:13 +01:00 committed by GitHub
parent 4ab3af0ede
commit 649ffcb66f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 66 additions and 48 deletions

2
go.mod
View File

@ -47,7 +47,7 @@ require (
github.com/hashicorp/hcl v1.0.0 github.com/hashicorp/hcl v1.0.0
github.com/hashicorp/hil v0.0.0-20160711231837-1e86c6b523c5 github.com/hashicorp/hil v0.0.0-20160711231837-1e86c6b523c5
github.com/hashicorp/mdns v1.0.1 // indirect github.com/hashicorp/mdns v1.0.1 // indirect
github.com/hashicorp/memberlist v0.1.5 github.com/hashicorp/memberlist v0.1.6
github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69
github.com/hashicorp/raft v1.1.2 github.com/hashicorp/raft v1.1.2
github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea

5
go.sum
View File

@ -185,8 +185,8 @@ github.com/hashicorp/mdns v1.0.1 h1:XFSOubp8KWB+Jd2PDyaX5xUd5bhSP/+pTDZVDMzZJM8=
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M= github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/memberlist v0.1.5 h1:AYBsgJOW9gab/toO5tEB8lWetVgDKZycqkebJ8xxpqM= github.com/hashicorp/memberlist v0.1.6 h1:ouPxvwKYaNZe+eTcHxYP0EblPduVLvIPycul+vv8his=
github.com/hashicorp/memberlist v0.1.5/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.1.6/go.mod h1:5VDNHjqFMgEcclnwmkCnC99IPwxBmIsxwY8qn+Nl0H4=
github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 h1:lc3c72qGlIMDqQpQH82Y4vaglRMMFdJbziYWriR4UcE= github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 h1:lc3c72qGlIMDqQpQH82Y4vaglRMMFdJbziYWriR4UcE=
github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q= github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q=
github.com/hashicorp/raft v1.1.1 h1:HJr7UE1x/JrJSc9Oy6aDBHtNHUUBHjcQjTgvUVihoZs= github.com/hashicorp/raft v1.1.1 h1:HJr7UE1x/JrJSc9Oy6aDBHtNHUUBHjcQjTgvUVihoZs=
@ -486,7 +486,6 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
istio.io/gogo-genproto v0.0.0-20190124151557-6d926a6e6feb/go.mod h1:eIDJ6jNk/IeJz6ODSksHl5Aiczy5JUq6vFhJWI5OtiI=
k8s.io/api v0.0.0-20180806132203-61b11ee65332/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/api v0.0.0-20180806132203-61b11ee65332/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
k8s.io/api v0.0.0-20190325185214-7544f9db76f6 h1:9MWtbqhwTyDvF4cS1qAhxDb9Mi8taXiAu+5nEacl7gY= k8s.io/api v0.0.0-20190325185214-7544f9db76f6 h1:9MWtbqhwTyDvF4cS1qAhxDb9Mi8taXiAu+5nEacl7gY=
k8s.io/api v0.0.0-20190325185214-7544f9db76f6/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= k8s.io/api v0.0.0-20190325185214-7544f9db76f6/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=

View File

@ -1,15 +0,0 @@
language: go
sudo: true
go:
- "1.x"
branches:
only:
- master
install: true
env:
- GO111MODULE=on # Enable Go modules in 1.11

View File

@ -1,6 +1,10 @@
DEPS := $(shell go list -f '{{range .Imports}}{{.}} {{end}}' ./...) SHELL := bash
test: subnet GOFILES ?= $(shell go list ./... | grep -v /vendor/)
default: test
test: vet subnet
go test ./... go test ./...
integ: subnet integ: subnet
@ -10,11 +14,20 @@ subnet:
./test/setup_subnet.sh ./test/setup_subnet.sh
cov: cov:
gocov test github.com/hashicorp/memberlist | gocov-html > /tmp/coverage.html go test ./... -coverprofile=coverage.out
open /tmp/coverage.html go tool cover -html=coverage.out
deps: format:
go get -t -d -v ./... @echo "--> Running go fmt"
echo $(DEPS) | xargs -n1 go get -d @go fmt $(GOFILES)
.PHONY: test cov integ vet:
@echo "--> Running go vet"
@go vet -tags '$(GOTAGS)' $(GOFILES); if [ $$? -eq 1 ]; then \
echo ""; \
echo "Vet found suspicious constructs. Please check the reported constructs"; \
echo "and fix them if necessary before submitting the code for review."; \
exit 1; \
fi
.PHONY: default test integ subnet cov format vet

View File

@ -1,4 +1,4 @@
# memberlist [![GoDoc](https://godoc.org/github.com/hashicorp/memberlist?status.png)](https://godoc.org/github.com/hashicorp/memberlist) [![Build Status](https://travis-ci.org/hashicorp/memberlist.svg?branch=master)](https://travis-ci.org/hashicorp/memberlist) # memberlist [![GoDoc](https://godoc.org/github.com/hashicorp/memberlist?status.png)](https://godoc.org/github.com/hashicorp/memberlist) [![CircleCI](https://circleci.com/gh/hashicorp/memberlist.svg?style=svg)](https://circleci.com/gh/hashicorp/memberlist)
memberlist is a [Go](http://www.golang.org) library that manages cluster memberlist is a [Go](http://www.golang.org) library that manages cluster
membership and member failure detection using a gossip based protocol. membership and member failure detection using a gossip based protocol.
@ -23,8 +23,6 @@ Please check your installation with:
go version go version
``` ```
Run `make deps` to fetch dependencies before building
## Usage ## Usage
Memberlist is surprisingly simple to use. An example is shown below: Memberlist is surprisingly simple to use. An example is shown below:

View File

@ -1,5 +1,7 @@
module github.com/hashicorp/memberlist module github.com/hashicorp/memberlist
go 1.12
require ( require (
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect

View File

@ -55,8 +55,8 @@ type Memberlist struct {
nodeLock sync.RWMutex nodeLock sync.RWMutex
nodes []*nodeState // Known nodes nodes []*nodeState // Known nodes
nodeMap map[string]*nodeState // Maps Addr.String() -> NodeState nodeMap map[string]*nodeState // Maps Node.Name -> NodeState
nodeTimers map[string]*suspicion // Maps Addr.String() -> suspicion timer nodeTimers map[string]*suspicion // Maps Node.Name -> suspicion timer
awareness *awareness awareness *awareness
tickerLock sync.Mutex tickerLock sync.Mutex
@ -472,7 +472,7 @@ func (m *Memberlist) UpdateNode(timeout time.Duration) error {
return nil return nil
} }
// SendTo is deprecated in favor of SendBestEffort, which requires a node to // Deprecated: SendTo is deprecated in favor of SendBestEffort, which requires a node to
// target. // target.
func (m *Memberlist) SendTo(to net.Addr, msg []byte) error { func (m *Memberlist) SendTo(to net.Addr, msg []byte) error {
// Encode as a user message // Encode as a user message
@ -484,12 +484,12 @@ func (m *Memberlist) SendTo(to net.Addr, msg []byte) error {
return m.rawSendMsgPacket(to.String(), nil, buf) return m.rawSendMsgPacket(to.String(), nil, buf)
} }
// SendToUDP is deprecated in favor of SendBestEffort. // Deprecated: SendToUDP is deprecated in favor of SendBestEffort.
func (m *Memberlist) SendToUDP(to *Node, msg []byte) error { func (m *Memberlist) SendToUDP(to *Node, msg []byte) error {
return m.SendBestEffort(to, msg) return m.SendBestEffort(to, msg)
} }
// SendToTCP is deprecated in favor of SendReliable. // Deprecated: SendToTCP is deprecated in favor of SendReliable.
func (m *Memberlist) SendToTCP(to *Node, msg []byte) error { func (m *Memberlist) SendToTCP(to *Node, msg []byte) error {
return m.SendReliable(to, msg) return m.SendReliable(to, msg)
} }
@ -525,7 +525,7 @@ func (m *Memberlist) Members() []*Node {
nodes := make([]*Node, 0, len(m.nodes)) nodes := make([]*Node, 0, len(m.nodes))
for _, n := range m.nodes { for _, n := range m.nodes {
if n.State != stateDead { if !n.DeadOrLeft() {
nodes = append(nodes, &n.Node) nodes = append(nodes, &n.Node)
} }
} }
@ -542,7 +542,7 @@ func (m *Memberlist) NumMembers() (alive int) {
defer m.nodeLock.RUnlock() defer m.nodeLock.RUnlock()
for _, n := range m.nodes { for _, n := range m.nodes {
if n.State != stateDead { if !n.DeadOrLeft() {
alive++ alive++
} }
} }
@ -579,9 +579,14 @@ func (m *Memberlist) Leave(timeout time.Duration) error {
return nil return nil
} }
// This dead message is special, because Node and From are the
// same. This helps other nodes figure out that a node left
// intentionally. When Node equals From, other nodes know for
// sure this node is gone.
d := dead{ d := dead{
Incarnation: state.Incarnation, Incarnation: state.Incarnation,
Node: state.Name, Node: state.Name,
From: state.Name,
} }
m.deadNode(&d) m.deadNode(&d)
@ -607,7 +612,7 @@ func (m *Memberlist) anyAlive() bool {
m.nodeLock.RLock() m.nodeLock.RLock()
defer m.nodeLock.RUnlock() defer m.nodeLock.RUnlock()
for _, n := range m.nodes { for _, n := range m.nodes {
if n.State != stateDead && n.Name != m.config.Name { if !n.DeadOrLeft() && n.Name != m.config.Name {
return true return true
} }
} }
@ -630,7 +635,7 @@ func (m *Memberlist) ProtocolVersion() uint8 {
return m.config.ProtocolVersion return m.config.ProtocolVersion
} }
// Shutdown will stop any background maintanence of network activity // Shutdown will stop any background maintenance of network activity
// for this memberlist, causing it to appear "dead". A leave message // for this memberlist, causing it to appear "dead". A leave message
// will not be broadcasted prior, so the cluster being left will have // will not be broadcasted prior, so the cluster being left will have
// to detect this node's shutdown using probing. If you wish to more // to detect this node's shutdown using probing. If you wish to more

View File

@ -669,7 +669,8 @@ func (m *Memberlist) rawSendMsgPacket(addr string, node *Node, msg []byte) error
} }
} }
// Try to look up the destination node // Try to look up the destination node. Note this will only work if the
// bare ip address is used as the node name, which is not guaranteed.
if node == nil { if node == nil {
toAddr, _, err := net.SplitHostPort(addr) toAddr, _, err := net.SplitHostPort(addr)
if err != nil { if err != nil {

View File

@ -19,6 +19,7 @@ const (
stateAlive nodeStateType = iota stateAlive nodeStateType = iota
stateSuspect stateSuspect
stateDead stateDead
stateLeft
) )
// Node represents a node in the cluster. // Node represents a node in the cluster.
@ -60,6 +61,10 @@ func (n *nodeState) Address() string {
return n.Node.Address() return n.Node.Address()
} }
func (n *nodeState) DeadOrLeft() bool {
return n.State == stateDead || n.State == stateLeft
}
// ackHandler is used to register handlers for incoming acks and nacks. // ackHandler is used to register handlers for incoming acks and nacks.
type ackHandler struct { type ackHandler struct {
ackFn func([]byte, time.Time) ackFn func([]byte, time.Time)
@ -218,7 +223,7 @@ START:
node = *m.nodes[m.probeIndex] node = *m.nodes[m.probeIndex]
if node.Name == m.config.Name { if node.Name == m.config.Name {
skip = true skip = true
} else if node.State == stateDead { } else if node.DeadOrLeft() {
skip = true skip = true
} }
@ -963,8 +968,8 @@ func (m *Memberlist) aliveNode(a *alive, notify chan struct{}, bootstrap bool) {
time.Since(state.StateChange) > m.config.DeadNodeReclaimTime) time.Since(state.StateChange) > m.config.DeadNodeReclaimTime)
// Allow the address to be updated if a dead node is being replaced. // Allow the address to be updated if a dead node is being replaced.
if state.State == stateDead && canReclaim { if state.State == stateLeft || (state.State == stateDead && canReclaim) {
m.logger.Printf("[INFO] memberlist: Updating address for failed node %s from %v:%d to %v:%d", m.logger.Printf("[INFO] memberlist: Updating address for left or failed node %s from %v:%d to %v:%d",
state.Name, state.Addr, state.Port, net.IP(a.Addr), a.Port) state.Name, state.Addr, state.Port, net.IP(a.Addr), a.Port)
updatesNode = true updatesNode = true
} else { } else {
@ -1059,8 +1064,8 @@ func (m *Memberlist) aliveNode(a *alive, notify chan struct{}, bootstrap bool) {
// Notify the delegate of any relevant updates // Notify the delegate of any relevant updates
if m.config.Events != nil { if m.config.Events != nil {
if oldState == stateDead { if oldState == stateDead || oldState == stateLeft {
// if Dead -> Alive, notify of join // if Dead/Left -> Alive, notify of join
m.config.Events.NotifyJoin(&state.Node) m.config.Events.NotifyJoin(&state.Node)
} else if !bytes.Equal(oldMeta, state.Meta) { } else if !bytes.Equal(oldMeta, state.Meta) {
@ -1179,7 +1184,7 @@ func (m *Memberlist) deadNode(d *dead) {
delete(m.nodeTimers, d.Node) delete(m.nodeTimers, d.Node)
// Ignore if node is already dead // Ignore if node is already dead
if state.State == stateDead { if state.DeadOrLeft() {
return return
} }
@ -1203,7 +1208,14 @@ func (m *Memberlist) deadNode(d *dead) {
// Update the state // Update the state
state.Incarnation = d.Incarnation state.Incarnation = d.Incarnation
state.State = stateDead
// If the dead message was send by the node itself, mark it is left
// instead of dead.
if d.Node == d.From {
state.State = stateLeft
} else {
state.State = stateDead
}
state.StateChange = time.Now() state.StateChange = time.Now()
// Notify of death // Notify of death
@ -1228,6 +1240,9 @@ func (m *Memberlist) mergeState(remote []pushNodeState) {
} }
m.aliveNode(&a, nil, false) m.aliveNode(&a, nil, false)
case stateLeft:
d := dead{Incarnation: r.Incarnation, Node: r.Name, From: r.Name}
m.deadNode(&d)
case stateDead: case stateDead:
// If the remote node believes a node is dead, we prefer to // If the remote node believes a node is dead, we prefer to
// suspect that node instead of declaring it dead instantly // suspect that node instead of declaring it dead instantly

2
vendor/modules.txt vendored
View File

@ -241,7 +241,7 @@ github.com/hashicorp/hil
github.com/hashicorp/hil/ast github.com/hashicorp/hil/ast
# github.com/hashicorp/mdns v1.0.1 # github.com/hashicorp/mdns v1.0.1
github.com/hashicorp/mdns github.com/hashicorp/mdns
# github.com/hashicorp/memberlist v0.1.5 # github.com/hashicorp/memberlist v0.1.6
github.com/hashicorp/memberlist github.com/hashicorp/memberlist
# github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 # github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69
github.com/hashicorp/net-rpc-msgpackrpc github.com/hashicorp/net-rpc-msgpackrpc