summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2023-05-22 00:06:30 +0300
committerPaul Buetow <paul@buetow.org>2023-05-22 00:06:30 +0300
commit14e73217895307983ae762cb5ffd29ac45d8d1d1 (patch)
treee90dd9743a30433348bfa9729011db1fad3886df /internal
parent1eb99dc0b6d04d85b9736ab5a050e08d410abb4a (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.go9
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
}