diff options
Diffstat (limited to 'internal/quorum')
| -rw-r--r-- | internal/quorum/quorum.go | 35 | ||||
| -rw-r--r-- | internal/quorum/quorum_test.go | 23 |
2 files changed, 53 insertions, 5 deletions
diff --git a/internal/quorum/quorum.go b/internal/quorum/quorum.go index d7fb866..79fea11 100644 --- a/internal/quorum/quorum.go +++ b/internal/quorum/quorum.go @@ -11,9 +11,10 @@ import ( ) type Quorum struct { - conf config.Config - votes map[string]vote.Vote - voteCh chan vote.Vote + conf config.Config + votes map[string]vote.Vote + voteCh chan vote.Vote + prevLiveNodes []string } type Score struct { @@ -38,11 +39,15 @@ func (quo Quorum) Start(ctx context.Context) <-chan []string { for { select { case <-time.After(vote.Expiry): - liveNodesCh <- quo.deleteExpiredVotes() + if liveNodes, changed := quo.liveNodes(); changed { + liveNodesCh <- liveNodes + } case vote := <-quo.voteCh: quo.vote(vote) + if liveNodes, changed := quo.liveNodes(); changed { + liveNodesCh <- liveNodes + } quo.score() - liveNodesCh <- quo.deleteExpiredVotes() case <-ctx.Done(): return } @@ -94,6 +99,26 @@ func (quo Quorum) score() (scores []Score) { return } +func (quo *Quorum) liveNodes() ([]string, bool) { + newLiveNodes := quo.deleteExpiredVotes() + defer func() { quo.prevLiveNodes = newLiveNodes }() + + if len(newLiveNodes) != len(quo.prevLiveNodes) { + return newLiveNodes, true + } + + for _, x := range newLiveNodes { + for _, y := range quo.prevLiveNodes { + if x == y { + continue + } + return newLiveNodes, false + } + } + + return newLiveNodes, true +} + func (quo Quorum) deleteExpiredVotes() (liveNodes []string) { var expired []string diff --git a/internal/quorum/quorum_test.go b/internal/quorum/quorum_test.go index ac5cbc6..176a4fb 100644 --- a/internal/quorum/quorum_test.go +++ b/internal/quorum/quorum_test.go @@ -125,3 +125,26 @@ func TestExpire(t *testing.T) { t.Errorf("Expected 'foo' to be the live node, but got : %v", liveNodes[0]) } } + +func TestLiveNodes(t *testing.T) { + conf := config.Config{Nodes: []string{"foo:1234", "bay:4321"}} + quo := New(conf) + + vote1 := vote.New(conf, " foo bar baz bay\n") + vote1.ExpiresAt = time.Now().Add(1 * time.Hour) + quo.vote(vote1) + + vote2 := vote.New(conf, " bay foo bar baz\n") + vote2.ExpiresAt = time.Now().Add(1 * time.Hour) + quo.vote(vote2) + + liveNodes, changed := quo.liveNodes() + if !changed { + t.Errorf("Expected live node list to be changed: %v", liveNodes) + } + + liveNodes, changed = quo.liveNodes() + if changed { + t.Errorf("Expected live node list not to be changed: %v", liveNodes) + } +} |
