From 755ddc99f75bf3fb677240807e02c8acff113e27 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Thu, 1 Jun 2023 06:43:35 -0700 Subject: [PATCH] Election! --- candidate.go | 6 ++++++ elect_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ voter.go | 3 ++- voter_test.go | 20 -------------------- 4 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 elect_test.go delete mode 100644 voter_test.go diff --git a/candidate.go b/candidate.go index f709b7d..9c49381 100644 --- a/candidate.go +++ b/candidate.go @@ -71,6 +71,10 @@ func (c *Candidate) State() CandidateState { return c.state } +func (c *Candidate) IsLeader() bool { + return c.State() == StateLeader +} + func (c *Candidate) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error( @@ -137,6 +141,8 @@ func (c *Candidate) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } + w.Header().Set("Content-Type", "application/json") + enc := json.NewEncoder(w) err = enc.Encode(c.resp) diff --git a/elect_test.go b/elect_test.go new file mode 100644 index 0000000..2c3d998 --- /dev/null +++ b/elect_test.go @@ -0,0 +1,42 @@ +package elect_test + +import ( + "fmt" + "net" + "net/http" + "testing" + "time" + + "github.com/gopatchy/elect" + "github.com/stretchr/testify/require" +) + +func TestSimple(t *testing.T) { + t.Parallel() + + c := elect.NewCandidate(1, "abc123") + + defer c.Stop() + + listener, err := net.ListenTCP("tcp", nil) + require.NoError(t, err) + + srv := &http.Server{ + Handler: c, + ReadHeaderTimeout: 30 * time.Second, + } + + go func() { + err := srv.Serve(listener) + require.ErrorIs(t, err, http.ErrServerClosed) + }() + + defer srv.Close() + + v := elect.NewVoter(fmt.Sprintf("http://%s/", listener.Addr()), "abc123") + require.NotNil(t, v) + + defer v.Stop() + + require.Eventually(t, c.IsLeader, 15*time.Second, 100*time.Millisecond) +} diff --git a/voter.go b/voter.go index dab3ccc..271eb53 100644 --- a/voter.go +++ b/voter.go @@ -77,7 +77,7 @@ func (v *Voter) loop(update <-chan time.Duration, done chan<- bool) { func (v *Voter) poll(update <-chan time.Duration, t *time.Ticker) bool { t2 := &time.Timer{} - if v.vote.NumPollsSinceChange < 10 { + if v.vote.NumPollsSinceChange < 11 { t2 = time.NewTimer(100 * time.Millisecond) defer t2.Stop() } @@ -110,6 +110,7 @@ func (v *Voter) sendVote() { resp, err := v.client.R(). SetHeader("Signature", mac(js, v.signingKey)). + SetHeader("Content-Type", "application/json"). SetBody(js). SetResult(vr). Post("") diff --git a/voter_test.go b/voter_test.go deleted file mode 100644 index 13820e2..0000000 --- a/voter_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package elect_test - -import ( - "testing" - "time" - - "github.com/gopatchy/elect" - "github.com/stretchr/testify/require" -) - -func TestNew(t *testing.T) { - t.Parallel() - - v := elect.NewVoter("https://[::1]:1234", "abc123") - require.NotNil(t, v) - - time.Sleep(1 * time.Second) - - defer v.Stop() -}