From ecf1887e5b197338c3a628385cbe24c615cca4cc Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 11 Apr 2016 11:42:08 +0100 Subject: [PATCH 1/2] Initialize Paxos quorum to 0 until this node needs to request consensus. With a 0 quorum we will participate in voting, but will not actively try to form a ring. --- ipam/allocator.go | 2 +- ipam/paxos/paxos.go | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ipam/allocator.go b/ipam/allocator.go index 20c78bd5..85b79f35 100644 --- a/ipam/allocator.go +++ b/ipam/allocator.go @@ -86,7 +86,7 @@ func NewAllocator(config Config) *Allocator { if config.IsObserver { participant = paxos.NewObserver() } else { - participant = paxos.NewNode(config.OurName, config.OurUID, 1) + participant = paxos.NewNode(config.OurName, config.OurUID, 0) } return &Allocator{ ourName: config.OurName, diff --git a/ipam/paxos/paxos.go b/ipam/paxos/paxos.go index fe10775b..4a2a53c1 100644 --- a/ipam/paxos/paxos.go +++ b/ipam/paxos/paxos.go @@ -241,6 +241,9 @@ func (node *Node) pickValue() Value { // Has a consensus been reached, based on the known claims of other nodes? func (node *Node) Consensus() (bool, AcceptedValue) { + if node.quorum == 0 { + return false, AcceptedValue{} + } counts := map[ProposalID]uint{} for _, claims := range node.knows { From c10d26cf02d0d7fe86e286b73936694cb2c57af3 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Mon, 11 Apr 2016 12:26:24 +0100 Subject: [PATCH 2/2] Fix up TestBootstrap after consensus changes --- ipam/allocator_test.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/ipam/allocator_test.go b/ipam/allocator_test.go index 300a147e..ff7146c4 100644 --- a/ipam/allocator_test.go +++ b/ipam/allocator_test.go @@ -117,6 +117,7 @@ func TestBootstrap(t *testing.T) { CheckAllExpectedMessagesSent(alloc1, alloc2) + // Check that tryPendingOps doesn't cause anything to happen here alloc1.actionChan <- func() { alloc1.tryPendingOps() } AssertNothingSent(t, done) @@ -129,14 +130,24 @@ func TestBootstrap(t *testing.T) { ExpectBroadcastMessage(alloc1, nil) alloc1.OnGossipBroadcast(alloc2.ourName, alloc2.Encode()) - // both nodes will get consensus now so initialize the ring - ExpectBroadcastMessage(alloc2, nil) + CheckAllExpectedMessagesSent(alloc1, alloc2) + + // at this point, both nodes have seen each other, but don't have a valid proposal + // so there is another exchange of messages ExpectBroadcastMessage(alloc2, nil) alloc2.OnGossipBroadcast(alloc1.ourName, alloc1.Encode()) + // we have consensus now so alloc1 will initialize the ring + ExpectBroadcastMessage(alloc1, nil) + alloc1.OnGossipBroadcast(alloc2.ourName, alloc2.Encode()) + + CheckAllExpectedMessagesSent(alloc1, alloc2) + + // alloc2 receives the ring and does not reply + alloc2.OnGossipBroadcast(alloc1.ourName, alloc1.Encode()) + CheckAllExpectedMessagesSent(alloc1, alloc2) - alloc1.OnGossipBroadcast(alloc2.ourName, alloc2.Encode()) // now alloc1 should have space AssertSent(t, done)