summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2023-05-21 23:57:53 +0300
committerPaul Buetow <paul@buetow.org>2023-05-21 23:57:53 +0300
commit1eb99dc0b6d04d85b9736ab5a050e08d410abb4a (patch)
tree77ec95510f0ce6de5f20aea2f5e7c12c91dd23bd /internal
parente958dc957a2339228bfe74865b4e1728484f4fd0 (diff)
refactor vote into its own package
Diffstat (limited to 'internal')
-rw-r--r--internal/quorum.go11
-rw-r--r--internal/quorum_test.go37
-rw-r--r--internal/server.go5
-rw-r--r--internal/tcpserver.go9
-rw-r--r--internal/vote/vote.go (renamed from internal/vote.go)20
-rw-r--r--internal/vote/vote_test.go46
-rw-r--r--internal/vote_test.go46
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")
- }
-}