diff options
| author | Paul Buetow <paul@buetow.org> | 2023-05-22 00:06:30 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2023-05-22 00:06:30 +0300 |
| commit | 14e73217895307983ae762cb5ffd29ac45d8d1d1 (patch) | |
| tree | e90dd9743a30433348bfa9729011db1fad3886df /internal | |
| parent | 1eb99dc0b6d04d85b9736ab5a050e08d410abb4a (diff) | |
move quorum into its own package
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/quorum/quorum.go (renamed from internal/quorum.go) | 32 | ||||
| -rw-r--r-- | internal/quorum/quorum_test.go (renamed from internal/quorum_test.go) | 60 | ||||
| -rw-r--r-- | internal/server.go | 9 |
3 files changed, 51 insertions, 50 deletions
diff --git a/internal/quorum.go b/internal/quorum/quorum.go index a64b07b..b28e8a9 100644 --- a/internal/quorum.go +++ b/internal/quorum/quorum.go @@ -1,4 +1,4 @@ -package internal +package quorum import ( "fmt" @@ -9,27 +9,27 @@ import ( "codeberg.org/snonux/gorum/internal/vote" ) -type quorumMap map[string]vote.Vote +type Quorum map[string]vote.Vote -type score struct { - id string - score int +type Score struct { + ID string + Value int } -func (q quorumMap) vote(v vote.Vote) { +func (q Quorum) Vote(v vote.Vote) { log.Printf("Adding vote %v", v) q[v.From] = v } -func (q quorumMap) winner(conf config.Config) (string, error) { - scores := q.score(conf) +func (q Quorum) Winner(conf config.Config) (string, error) { + scores := q.Score(conf) if len(scores) == 0 { return "", fmt.Errorf("unable to find a winner, empty score list") } - return scores[0].id, nil + return scores[0].ID, nil } -func (q quorumMap) score(conf config.Config) (scores []score) { +func (q Quorum) Score(conf config.Config) (scores []Score) { scoreMap := make(map[string]int) for _, vote := range q { @@ -40,24 +40,24 @@ func (q quorumMap) score(conf config.Config) (scores []score) { } for id, score_ := range scoreMap { - scores = append(scores, score{id, score_}) + scores = append(scores, Score{id, score_}) } sort.Slice(scores, func(i, j int) bool { - if scores[i].score != scores[j].score { - return scores[i].score > scores[j].score + if scores[i].Value != scores[j].Value { + return scores[i].Value > scores[j].Value } // Score tie, use participant number. - i_, _ := conf.ParticipantNumber(scores[i].id) - j_, _ := conf.ParticipantNumber(scores[j].id) + i_, _ := conf.ParticipantNumber(scores[i].ID) + j_, _ := conf.ParticipantNumber(scores[j].ID) return i_ < j_ }) return } -func (q quorumMap) cleanExpired() { +func (q Quorum) CleanExpired() { var expired []string for from, vote := range q { diff --git a/internal/quorum_test.go b/internal/quorum/quorum_test.go index 2001937..3a0f186 100644 --- a/internal/quorum_test.go +++ b/internal/quorum/quorum_test.go @@ -1,4 +1,4 @@ -package internal +package quorum import ( "testing" @@ -9,87 +9,87 @@ import ( ) func TestScore(t *testing.T) { - quorum := make(quorumMap) + quo := make(Quorum) conf := config.Config{Participants: []string{"foo:1234", "bar:4321", "baz:3444"}} vote1 := vote.New(conf, "foo:334234", "foo bar\n") vote1.ExpiresAt = time.Now().Add(1 * time.Hour) - quorum.vote(vote1) + quo.Vote(vote1) vote2 := vote.New(conf, "bar:334234", "bar baz\n") vote2.ExpiresAt = time.Now().Add(1 * time.Hour) - quorum.vote(vote2) + quo.Vote(vote2) vote3_dup := vote.New(conf, "bar:33234", "bar baz\n") vote3_dup.ExpiresAt = time.Now().Add(1 * time.Hour) - quorum.vote(vote3_dup) + quo.Vote(vote3_dup) vote4 := vote.New(conf, "baz:334234", "foo bar baz\n") vote4.ExpiresAt = time.Now().Add(1 * time.Hour) - quorum.vote(vote4) + quo.Vote(vote4) - scores := quorum.score(conf) + scores := quo.Score(conf) if len(scores) != 3 { t.Errorf("Expected scores to be of length 3: %v", scores) } - if scores[0].id != "bar" || scores[0].score != 3 { + if scores[0].ID != "bar" || scores[0].Value != 3 { t.Errorf("Expected score[0] to be {bar,3}: %v", scores[0]) } } func TestTieScore(t *testing.T) { - addVotes := func(conf config.Config, quorum quorumMap) { + addVotes := func(conf config.Config, quo Quorum) { vote1 := vote.New(conf, "foo:334234", "foo bar baz\n") vote1.ExpiresAt = time.Now().Add(1 * time.Hour) - quorum.vote(vote1) + quo.Vote(vote1) vote2 := vote.New(conf, "bar:334234", "foo bar baz\n") vote2.ExpiresAt = time.Now().Add(1 * time.Hour) - quorum.vote(vote2) + quo.Vote(vote2) vote3 := vote.New(conf, "baz:334234", "foo bar baz\n") vote3.ExpiresAt = time.Now().Add(1 * time.Hour) - quorum.vote(vote3) + quo.Vote(vote3) } t.Run("First tie score test", func(t *testing.T) { - quorum := make(quorumMap) + quo := make(Quorum) // If it is a tie, the first particpant (here: "foo") will win. conf := config.Config{Participants: []string{"foo:1234", "bar:4321", "baz:3444"}} - addVotes(conf, quorum) - scores := quorum.score(conf) + addVotes(conf, quo) + scores := quo.Score(conf) if len(scores) != 3 { t.Errorf("Expected scores to be of length 3: %v", scores) } - if scores[0].id != "foo" || scores[0].score != 3 { + if scores[0].ID != "foo" || scores[0].Value != 3 { t.Errorf("Expected score[0] to be {foo,3}: %v", scores[0]) } - winner, _ := quorum.winner(conf) + winner, _ := quo.Winner(conf) if winner != "foo" { t.Errorf("Expected the winner to be foo but is: %s", winner) } }) t.Run("Second tie score test", func(t *testing.T) { - quorum := make(quorumMap) + quo := make(Quorum) // If it is a tie, the first particpant (here: "bar") will win. conf := config.Config{Participants: []string{"bar:1234", "foo:4321", "baz:3444"}} - addVotes(conf, quorum) - scores := quorum.score(conf) + addVotes(conf, quo) + scores := quo.Score(conf) if len(scores) != 3 { t.Errorf("Expected scores to be of length 3: %v", scores) } - if scores[0].id != "bar" || scores[0].score != 3 { + if scores[0].ID != "bar" || scores[0].Value != 3 { t.Errorf("Expected score[0] to be {bar,3}: %v", scores[0]) } - winner, _ := quorum.winner(conf) + winner, _ := quo.Winner(conf) if winner != "bar" { t.Errorf("Expected the winner to be bar but is: %s", winner) } @@ -97,23 +97,23 @@ func TestTieScore(t *testing.T) { } func TestCleanExpired(t *testing.T) { - quorum := make(quorumMap) + quo := make(Quorum) conf := config.Config{Participants: []string{"foo:1234", "bay:4321"}} vote1 := vote.New(conf, "foo:334234", " foo bar baz bay\n") vote1.ExpiresAt = time.Now().Add(1 * time.Hour) - quorum.vote(vote1) + quo.Vote(vote1) vote2 := vote.New(conf, "bar:334234", " foo bar baz bay\n") vote2.ExpiresAt = time.Now() - quorum.vote(vote2) + quo.Vote(vote2) - if len(quorum) != 2 { - t.Errorf("Expected to have two votes before expiry: %v", quorum) + if len(quo) != 2 { + t.Errorf("Expected to have two votes before expiry: %v", quo) } - quorum.cleanExpired() - if len(quorum) != 1 { - t.Errorf("Expected to have only one vote after expiry: %v", quorum) + quo.CleanExpired() + if len(quo) != 1 { + t.Errorf("Expected to have only one vote after expiry: %v", quo) } } diff --git a/internal/server.go b/internal/server.go index 05babc0..3c37d6a 100644 --- a/internal/server.go +++ b/internal/server.go @@ -6,26 +6,27 @@ import ( "time" "codeberg.org/snonux/gorum/internal/config" + "codeberg.org/snonux/gorum/internal/quorum" "codeberg.org/snonux/gorum/internal/vote" ) func runServer(ctx context.Context, conf config.Config) { ch := make(chan vote.Vote) - quorum := make(quorumMap) + quo := make(quorum.Quorum) go func() { for { select { case vote := <-ch: - quorum.vote(vote) - winner, err := quorum.winner(conf) + quo.Vote(vote) + winner, err := quo.Winner(conf) if err != nil { log.Println(err.Error()) continue } log.Printf("The current leader node is %s", winner) case <-time.After(vote.Expiry): - quorum.cleanExpired() + quo.CleanExpired() case <-ctx.Done(): return } |
