diff options
Diffstat (limited to 'internal/quorum/quorum.go')
| -rw-r--r-- | internal/quorum/quorum.go | 71 |
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 } |
