summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2023-05-28 21:26:36 +0300
committerPaul Buetow <paul@buetow.org>2023-05-28 21:26:36 +0300
commitd0d7460ab74d7467a8c2bcc7d8c384cb0196b807 (patch)
tree1330da155d13ebf555bf6c41212a7083d53fd182
parent16fed128d96722f930cc5168c3aaea11ee775159 (diff)
fix (another) race condition
-rw-r--r--internal/quorum/quorum.go12
-rw-r--r--internal/quorum/quorum_test.go20
-rw-r--r--internal/server/server.go2
3 files changed, 21 insertions, 13 deletions
diff --git a/internal/quorum/quorum.go b/internal/quorum/quorum.go
index b31a472..6c4bcb6 100644
--- a/internal/quorum/quorum.go
+++ b/internal/quorum/quorum.go
@@ -14,6 +14,7 @@ import (
type Quorum struct {
conf config.Config
votes map[string]vote.Vote
+ inCh chan vote.Vote
}
type Score struct {
@@ -25,6 +26,7 @@ func New(conf config.Config) Quorum {
return Quorum{
conf: conf,
votes: make(map[string]vote.Vote),
+ inCh: make(chan vote.Vote),
}
}
@@ -38,6 +40,9 @@ func (quo Quorum) Start(ctx context.Context) chan string {
for {
select {
case <-time.After(vote.Expiry):
+ quo.deleteExpiredVotes()
+ case vote := <-quo.inCh:
+ quo.vote(vote)
winner, err := quo.winner()
if err != nil {
log.Println(err)
@@ -65,6 +70,11 @@ func (quo Quorum) Start(ctx context.Context) chan string {
}
func (quo Quorum) Vote(v vote.Vote) {
+ log.Printf("Queing vote %v", v)
+ quo.inCh <- v
+}
+
+func (quo Quorum) vote(v vote.Vote) {
log.Printf("Adding vote %v", v)
quo.votes[v.From] = v
}
@@ -105,7 +115,7 @@ func (quo Quorum) score() (scores []Score) {
return
}
-func (quo Quorum) DeleteExpiredVotes() {
+func (quo Quorum) deleteExpiredVotes() {
var expired []string
for from, vote := range quo.votes {
diff --git a/internal/quorum/quorum_test.go b/internal/quorum/quorum_test.go
index 3e05692..d0f7ec7 100644
--- a/internal/quorum/quorum_test.go
+++ b/internal/quorum/quorum_test.go
@@ -14,19 +14,19 @@ func TestScore(t *testing.T) {
vote1 := vote.New(conf, "foo:334234", "foo bar\n")
vote1.ExpiresAt = time.Now().Add(1 * time.Hour)
- quo.Vote(vote1)
+ quo.vote(vote1)
vote2 := vote.New(conf, "bar:334234", "bar baz\n")
vote2.ExpiresAt = time.Now().Add(1 * time.Hour)
- quo.Vote(vote2)
+ quo.vote(vote2)
vote3_dup := vote.New(conf, "bar:33234", "bar baz\n")
vote3_dup.ExpiresAt = time.Now().Add(1 * time.Hour)
- quo.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)
- quo.Vote(vote4)
+ quo.vote(vote4)
scores := quo.score()
if len(scores) != 3 {
@@ -42,15 +42,15 @@ func TestTieScore(t *testing.T) {
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)
- quo.Vote(vote1)
+ quo.vote(vote1)
vote2 := vote.New(conf, "bar:334234", "foo bar baz\n")
vote2.ExpiresAt = time.Now().Add(1 * time.Hour)
- quo.Vote(vote2)
+ quo.vote(vote2)
vote3 := vote.New(conf, "baz:334234", "foo bar baz\n")
vote3.ExpiresAt = time.Now().Add(1 * time.Hour)
- quo.Vote(vote3)
+ quo.vote(vote3)
}
t.Run("First tie score test", func(t *testing.T) {
@@ -102,17 +102,17 @@ func TestExpire(t *testing.T) {
vote1 := vote.New(conf, "foo:334234", " foo bar baz bay\n")
vote1.ExpiresAt = time.Now().Add(1 * time.Hour)
- quo.Vote(vote1)
+ quo.vote(vote1)
vote2 := vote.New(conf, "bar:334234", " foo bar baz bay\n")
vote2.ExpiresAt = time.Now()
- quo.Vote(vote2)
+ quo.vote(vote2)
if len(quo.votes) != 2 {
t.Errorf("Expected to have two votes before expiry: %v", quo)
}
- quo.DeleteExpiredVotes()
+ quo.deleteExpiredVotes()
if len(quo.votes) != 1 {
t.Errorf("Expected to have only one vote after expiry: %v", quo)
}
diff --git a/internal/server/server.go b/internal/server/server.go
index a56899a..dc1fd90 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -38,8 +38,6 @@ func run(ctx context.Context, conf config.Config, quo quorum.Quorum) error {
select {
case vote := <-ch:
quo.Vote(vote)
- case <-time.After(vote.Expiry):
- quo.DeleteExpiredVotes()
case <-serverCtx.Done():
return
}