Election!
This commit is contained in:
@@ -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)
|
||||
|
||||
42
elect_test.go
Normal file
42
elect_test.go
Normal file
@@ -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)
|
||||
}
|
||||
3
voter.go
3
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("")
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user