summaryrefslogtreecommitdiff
path: root/internal/quorum/quorum.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/quorum/quorum.go')
-rw-r--r--internal/quorum/quorum.go71
1 files changed, 25 insertions, 46 deletions
diff --git a/internal/quorum/quorum.go b/internal/quorum/quorum.go
index 01c861a..b299460 100644
--- a/internal/quorum/quorum.go
+++ b/internal/quorum/quorum.go
@@ -2,7 +2,6 @@ package quorum
import (
"context"
- "fmt"
"log"
"sort"
"time"
@@ -12,9 +11,9 @@ import (
)
type Quorum struct {
- conf config.Config
- votes map[string]vote.Vote
- inCh chan vote.Vote
+ conf config.Config
+ votes map[string]vote.Vote
+ voteCh chan vote.Vote
}
type Score struct {
@@ -24,54 +23,37 @@ type Score struct {
func New(conf config.Config) Quorum {
return Quorum{
- conf: conf,
- votes: make(map[string]vote.Vote),
- inCh: make(chan vote.Vote),
+ conf: conf,
+ votes: make(map[string]vote.Vote),
+ voteCh: make(chan vote.Vote),
}
}
-func (quo Quorum) Start(ctx context.Context) chan string {
- ch := make(chan string, 1)
+func (quo Quorum) Start(ctx context.Context) <-chan []string {
+ liveNodesCh := make(chan []string)
go func() {
- defer close(ch)
- var lastWinner string
+ defer close(liveNodesCh)
for {
select {
case <-time.After(vote.Expiry):
- quo.deleteExpiredVotes()
- case vote := <-quo.inCh:
+ liveNodesCh <- quo.deleteExpiredVotes()
+ case vote := <-quo.voteCh:
quo.vote(vote)
- winner, err := quo.winner()
- if err != nil {
- log.Println(err)
- continue
- }
- if lastWinner == winner {
- continue
- }
- lastWinner = winner
-
- // Remove current channel entry, and update with new winner
- select {
- case <-ch:
- default:
- }
- ch <- winner
-
+ liveNodesCh <- quo.deleteExpiredVotes()
case <-ctx.Done():
return
}
}
}()
- return ch
+ return liveNodesCh
}
func (quo Quorum) Vote(v vote.Vote) {
log.Printf("Queing vote %v", v)
- quo.inCh <- v
+ quo.voteCh <- v
}
func (quo Quorum) vote(v vote.Vote) {
@@ -79,14 +61,6 @@ func (quo Quorum) vote(v vote.Vote) {
quo.votes[v.From] = v
}
-func (quo Quorum) winner() (string, error) {
- scores := quo.score()
- if len(scores) == 0 {
- return "", fmt.Errorf("unable to find a winner, empty score list")
- }
- return scores[0].ID, nil
-}
-
func (quo Quorum) score() (scores []Score) {
scoreMap := make(map[string]int)
@@ -109,25 +83,30 @@ func (quo Quorum) score() (scores []Score) {
return scores[i].Value > scores[j].Value
}
- // Score tie, use participant number.
- i_, _ := quo.conf.ParticipantNumber(scores[i].ID)
- j_, _ := quo.conf.ParticipantNumber(scores[j].ID)
+ // Score tie, use node number.
+ i_, _ := quo.conf.NodeNumber(scores[i].ID)
+ j_, _ := quo.conf.NodeNumber(scores[j].ID)
return i_ < j_
})
+ log.Println("Scores are ", scores)
return
}
-func (quo Quorum) deleteExpiredVotes() {
+func (quo Quorum) deleteExpiredVotes() (liveNodes []string) {
var expired []string
- for from, vote := range quo.votes {
+ for fromNode, vote := range quo.votes {
if vote.Expired() {
- expired = append(expired, from)
+ expired = append(expired, fromNode)
+ continue
}
+ liveNodes = append(liveNodes, fromNode)
}
for _, e := range expired {
delete(quo.votes, e)
}
+
+ return
}