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/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) 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 {