diff options
| author | Paul Buetow <paul@buetow.org> | 2023-05-21 23:57:53 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2023-05-21 23:57:53 +0300 |
| commit | 1eb99dc0b6d04d85b9736ab5a050e08d410abb4a (patch) | |
| tree | 77ec95510f0ce6de5f20aea2f5e7c12c91dd23bd /internal | |
| parent | e958dc957a2339228bfe74865b4e1728484f4fd0 (diff) | |
refactor vote into its own package
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/quorum.go | 11 | ||||
| -rw-r--r-- | internal/quorum_test.go | 37 | ||||
| -rw-r--r-- | internal/server.go | 5 | ||||
| -rw-r--r-- | internal/tcpserver.go | 9 | ||||
| -rw-r--r-- | internal/vote/vote.go (renamed from internal/vote.go) | 20 | ||||
| -rw-r--r-- | internal/vote/vote_test.go | 46 | ||||
| -rw-r--r-- | internal/vote_test.go | 46 |
7 files changed, 90 insertions, 84 deletions
diff --git a/internal/quorum.go b/internal/quorum.go index b680378..a64b07b 100644 --- a/internal/quorum.go +++ b/internal/quorum.go @@ -6,18 +6,19 @@ import ( "sort" "codeberg.org/snonux/gorum/internal/config" + "codeberg.org/snonux/gorum/internal/vote" ) -type quorumMap map[string]vote +type quorumMap map[string]vote.Vote type score struct { id string score int } -func (q quorumMap) vote(v vote) { +func (q quorumMap) vote(v vote.Vote) { log.Printf("Adding vote %v", v) - q[v.from] = v + q[v.From] = v } func (q quorumMap) winner(conf config.Config) (string, error) { @@ -32,7 +33,7 @@ func (q quorumMap) score(conf config.Config) (scores []score) { scoreMap := make(map[string]int) for _, vote := range q { - for _, id := range vote.ids { + for _, id := range vote.IDs { score, _ := scoreMap[id] scoreMap[id] = score + 1 } @@ -60,7 +61,7 @@ func (q quorumMap) cleanExpired() { var expired []string for from, vote := range q { - if vote.expired() { + if vote.Expired() { expired = append(expired, from) } } diff --git a/internal/quorum_test.go b/internal/quorum_test.go index 6da4956..2001937 100644 --- a/internal/quorum_test.go +++ b/internal/quorum_test.go @@ -5,26 +5,27 @@ import ( "time" "codeberg.org/snonux/gorum/internal/config" + "codeberg.org/snonux/gorum/internal/vote" ) func TestScore(t *testing.T) { quorum := make(quorumMap) conf := config.Config{Participants: []string{"foo:1234", "bar:4321", "baz:3444"}} - vote1 := newVote(conf, "foo:334234", "foo bar\n") - vote1.expiresAt = time.Now().Add(1 * time.Hour) + vote1 := vote.New(conf, "foo:334234", "foo bar\n") + vote1.ExpiresAt = time.Now().Add(1 * time.Hour) quorum.vote(vote1) - vote2 := newVote(conf, "bar:334234", "bar baz\n") - vote2.expiresAt = time.Now().Add(1 * time.Hour) + vote2 := vote.New(conf, "bar:334234", "bar baz\n") + vote2.ExpiresAt = time.Now().Add(1 * time.Hour) quorum.vote(vote2) - vote3_dup := newVote(conf, "bar:33234", "bar baz\n") - vote3_dup.expiresAt = time.Now().Add(1 * time.Hour) + vote3_dup := vote.New(conf, "bar:33234", "bar baz\n") + vote3_dup.ExpiresAt = time.Now().Add(1 * time.Hour) quorum.vote(vote3_dup) - vote4 := newVote(conf, "baz:334234", "foo bar baz\n") - vote4.expiresAt = time.Now().Add(1 * time.Hour) + vote4 := vote.New(conf, "baz:334234", "foo bar baz\n") + vote4.ExpiresAt = time.Now().Add(1 * time.Hour) quorum.vote(vote4) scores := quorum.score(conf) @@ -39,16 +40,16 @@ func TestScore(t *testing.T) { func TestTieScore(t *testing.T) { addVotes := func(conf config.Config, quorum quorumMap) { - vote1 := newVote(conf, "foo:334234", "foo bar baz\n") - vote1.expiresAt = time.Now().Add(1 * time.Hour) + vote1 := vote.New(conf, "foo:334234", "foo bar baz\n") + vote1.ExpiresAt = time.Now().Add(1 * time.Hour) quorum.vote(vote1) - vote2 := newVote(conf, "bar:334234", "foo bar baz\n") - vote2.expiresAt = time.Now().Add(1 * time.Hour) + vote2 := vote.New(conf, "bar:334234", "foo bar baz\n") + vote2.ExpiresAt = time.Now().Add(1 * time.Hour) quorum.vote(vote2) - vote3 := newVote(conf, "baz:334234", "foo bar baz\n") - vote3.expiresAt = time.Now().Add(1 * time.Hour) + vote3 := vote.New(conf, "baz:334234", "foo bar baz\n") + vote3.ExpiresAt = time.Now().Add(1 * time.Hour) quorum.vote(vote3) } @@ -99,12 +100,12 @@ func TestCleanExpired(t *testing.T) { quorum := make(quorumMap) conf := config.Config{Participants: []string{"foo:1234", "bay:4321"}} - vote1 := newVote(conf, "foo:334234", " foo bar baz bay\n") - vote1.expiresAt = time.Now().Add(1 * time.Hour) + vote1 := vote.New(conf, "foo:334234", " foo bar baz bay\n") + vote1.ExpiresAt = time.Now().Add(1 * time.Hour) quorum.vote(vote1) - vote2 := newVote(conf, "bar:334234", " foo bar baz bay\n") - vote2.expiresAt = time.Now() + vote2 := vote.New(conf, "bar:334234", " foo bar baz bay\n") + vote2.ExpiresAt = time.Now() quorum.vote(vote2) if len(quorum) != 2 { diff --git a/internal/server.go b/internal/server.go index e5e55d1..05babc0 100644 --- a/internal/server.go +++ b/internal/server.go @@ -6,10 +6,11 @@ import ( "time" "codeberg.org/snonux/gorum/internal/config" + "codeberg.org/snonux/gorum/internal/vote" ) func runServer(ctx context.Context, conf config.Config) { - ch := make(chan vote) + ch := make(chan vote.Vote) quorum := make(quorumMap) go func() { @@ -23,7 +24,7 @@ func runServer(ctx context.Context, conf config.Config) { continue } log.Printf("The current leader node is %s", winner) - case <-time.After(voteExpiry): + case <-time.After(vote.Expiry): quorum.cleanExpired() case <-ctx.Done(): return diff --git a/internal/tcpserver.go b/internal/tcpserver.go index 0f9c006..b1fd11e 100644 --- a/internal/tcpserver.go +++ b/internal/tcpserver.go @@ -8,9 +8,12 @@ import ( "net" "codeberg.org/snonux/gorum/internal/config" + "codeberg.org/snonux/gorum/internal/vote" ) -func startTcpServer(ctx context.Context, conf config.Config, ch chan<- vote) error { +func startTcpServer(ctx context.Context, conf config.Config, + ch chan<- vote.Vote) error { + listener, err := net.Listen("tcp", conf.Address) if err != nil { return fmt.Errorf("Error starting TCP server: %s", err.Error()) @@ -38,7 +41,7 @@ func startTcpServer(ctx context.Context, conf config.Config, ch chan<- vote) err } func handleConnection(ctx context.Context, conf config.Config, - conn net.Conn, ch chan<- vote) { + conn net.Conn, ch chan<- vote.Vote) { defer conn.Close() remoteAddr := conn.RemoteAddr().String() @@ -57,7 +60,7 @@ func handleConnection(ctx context.Context, conf config.Config, } log.Printf("Received message from %s: %s", remoteAddr, message) - ch <- newVote(conf, remoteAddr, message) + ch <- vote.New(conf, remoteAddr, message) conn.Write([]byte(message)) } diff --git a/internal/vote.go b/internal/vote/vote.go index a9c93f0..079e021 100644 --- a/internal/vote.go +++ b/internal/vote/vote.go @@ -1,4 +1,4 @@ -package internal +package vote import ( "log" @@ -9,15 +9,15 @@ import ( "codeberg.org/snonux/gorum/internal/utils" ) -const voteExpiry = 20 * time.Second +const Expiry = 20 * time.Second -type vote struct { - from string - ids []string - expiresAt time.Time +type Vote struct { + From string + IDs []string + ExpiresAt time.Time } -func newVote(conf config.Config, from, message string) vote { +func New(conf config.Config, from, message string) Vote { var ids []string for _, id := range strings.Split(strings.TrimSpace(message), " ") { if !conf.IsParticipant(id) { @@ -27,10 +27,10 @@ func newVote(conf config.Config, from, message string) vote { ids = append(ids, id) } - return vote{utils.StripPort(from), ids, time.Now().Add(voteExpiry)} + return Vote{utils.StripPort(from), ids, time.Now().Add(Expiry)} } -func (v vote) expired() bool { +func (v Vote) Expired() bool { now := time.Now() - return now.After(v.expiresAt) || now.Equal(v.expiresAt) + return now.After(v.ExpiresAt) || now.Equal(v.ExpiresAt) } diff --git a/internal/vote/vote_test.go b/internal/vote/vote_test.go new file mode 100644 index 0000000..0986e00 --- /dev/null +++ b/internal/vote/vote_test.go @@ -0,0 +1,46 @@ +package vote + +import ( + "testing" + "time" + + "codeberg.org/snonux/gorum/internal/config" +) + +func TestVote(t *testing.T) { + conf := config.Config{Participants: []string{"foo:1234", "bay:4321"}} + v := New(conf, "earth:334234", " foo bar baz bay\n") + + if v.From != "earth" { + t.Errorf("Expected vote to come from earth but came from %s", v.From) + } + + if len(v.IDs) != 2 { + t.Errorf("Expected vote length to be 2 but is %d", len(v.IDs)) + } + + if v.IDs[0] != "foo" { + t.Errorf("Expected vote 1 to be foo but is %s", v.IDs[0]) + } + + if v.IDs[1] != "bay" { + t.Errorf("Expected vote 2 to be bay but is %s", v.IDs[1]) + } +} + +func TestVoteExpiry(t *testing.T) { + conf := config.Config{Participants: []string{"foo:1234", "bay:4321"}} + v := New(conf, "earth:334234", " foo bar baz bay\n") + + // Set expiry 1h into the future + v.ExpiresAt = time.Now().Add(1 * time.Hour) + if v.Expired() { + t.Errorf("Didn't expect vote to be expired") + } + + // Set expiry to now + v.ExpiresAt = time.Now() + if !v.Expired() { + t.Errorf("Expected vote to be expired") + } +} diff --git a/internal/vote_test.go b/internal/vote_test.go deleted file mode 100644 index 77e54c8..0000000 --- a/internal/vote_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package internal - -import ( - "testing" - "time" - - "codeberg.org/snonux/gorum/internal/config" -) - -func TestVote(t *testing.T) { - conf := config.Config{Participants: []string{"foo:1234", "bay:4321"}} - v := newVote(conf, "earth:334234", " foo bar baz bay\n") - - if v.from != "earth" { - t.Errorf("Expected vote to come from earth but came from %s", v.from) - } - - if len(v.ids) != 2 { - t.Errorf("Expected vote length to be 2 but is %d", len(v.ids)) - } - - if v.ids[0] != "foo" { - t.Errorf("Expected vote 1 to be foo but is %s", v.ids[0]) - } - - if v.ids[1] != "bay" { - t.Errorf("Expected vote 2 to be bay but is %s", v.ids[1]) - } -} - -func TestVoteExpiry(t *testing.T) { - conf := config.Config{Participants: []string{"foo:1234", "bay:4321"}} - v := newVote(conf, "earth:334234", " foo bar baz bay\n") - - // Set expiry 1h into the future - v.expiresAt = time.Now().Add(1 * time.Hour) - if v.expired() { - t.Errorf("Didn't expect vote to be expired") - } - - // Set expiry to now - v.expiresAt = time.Now() - if !v.expired() { - t.Errorf("Expected vote to be expired") - } -} |
