diff options
| author | Paul Buetow <paul@buetow.org> | 2023-05-28 21:26:36 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2023-05-28 21:26:36 +0300 |
| commit | d0d7460ab74d7467a8c2bcc7d8c384cb0196b807 (patch) | |
| tree | 1330da155d13ebf555bf6c41212a7083d53fd182 | |
| parent | 16fed128d96722f930cc5168c3aaea11ee775159 (diff) | |
fix (another) race condition
| -rw-r--r-- | internal/quorum/quorum.go | 12 | ||||
| -rw-r--r-- | internal/quorum/quorum_test.go | 20 | ||||
| -rw-r--r-- | internal/server/server.go | 2 |
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 } |
