1
0
Fork 0

Push in read-only status

Similar to DNS autoclustering, the Store doesn't know its intended
read-only state.
master
Philip O'Toole 9 months ago
parent f3b8f023dc
commit e700b03291

@ -322,7 +322,7 @@ func createDiscoService(cfg *Config, str *store.Store) (*disco.Service, error) {
return nil, fmt.Errorf("invalid disco service: %s", cfg.DiscoMode)
}
return disco.NewService(c, str), nil
return disco.NewService(c, str, disco.VoterSuffrage(!cfg.RaftNonVoter)), nil
}
func startHTTPService(cfg *Config, str *store.Store, cltr *cluster.Client, credStr *auth.CredentialsStore) (*httpd.Service, error) {

@ -37,14 +37,33 @@ type Store interface {
// IsLeader returns whether this node is the Leader.
IsLeader() bool
// IsVoter returns whether this node is a voter. Only Voters can be Leaders.
IsVoter() (bool, error)
// RegisterLeaderChange registers a channel that will be notified when
// a leadership change occurs.
RegisterLeaderChange(c chan<- struct{})
}
// Suffrage is the type of suffrage -- voting or non-voting -- a node has.
type Suffrage int
const (
SuffrageUnknown Suffrage = iota
Voter
NonVoter
)
// VoterSuffrage returns a Suffrage based on the given boolean.
func VoterSuffrage(b bool) Suffrage {
if b {
return Voter
}
return NonVoter
}
// IsVoter returns whether the Suffrage indicates a Voter.
func (s Suffrage) IsVoter() bool {
return s == Voter
}
// Service represents a Discovery Service instance.
type Service struct {
RegisterInterval time.Duration
@ -52,6 +71,7 @@ type Service struct {
c Client
s Store
suf Suffrage
logger *log.Logger
@ -60,11 +80,11 @@ type Service struct {
}
// NewService returns an instantiated Discovery Service.
func NewService(c Client, s Store) *Service {
func NewService(c Client, s Store, suf Suffrage) *Service {
return &Service{
c: c,
s: s,
suf: suf,
RegisterInterval: 3 * time.Second,
ReportInterval: 10 * time.Second,
logger: log.New(os.Stderr, "[disco] ", log.LstdFlags),
@ -84,7 +104,7 @@ func (s *Service) Register(id, apiAddr, addr string) (bool, string, error) {
return false, cRaftAddr, nil
}
if s.isVoter() {
if s.suf.IsVoter() {
ok, err = s.c.InitializeLeader(id, apiAddr, addr)
if err != nil {
s.logger.Printf("failed to initialize as Leader: %s", err.Error())
@ -157,8 +177,3 @@ func (s *Service) updateContact(t time.Time) {
defer s.mu.Unlock()
s.lastContact = t
}
func (s *Service) isVoter() bool {
v, _ := s.s.IsVoter()
return v
}

@ -7,7 +7,7 @@ import (
)
func Test_NewServce(t *testing.T) {
s := NewService(&mockClient{}, &mockStore{})
s := NewService(&mockClient{}, &mockStore{}, Voter)
if s == nil {
t.Fatalf("service is nil")
}
@ -24,7 +24,7 @@ func Test_RegisterGetLeaderOK(t *testing.T) {
}
c := &mockStore{}
s := NewService(m, c)
s := NewService(m, c, Voter)
s.RegisterInterval = 10 * time.Millisecond
ok, addr, err := s.Register("1", "localhost:4001", "localhost:4002")
@ -52,7 +52,7 @@ func Test_RegisterInitializeLeader(t *testing.T) {
}
c := &mockStore{}
s := NewService(m, c)
s := NewService(m, c, Voter)
s.RegisterInterval = 10 * time.Millisecond
ok, addr, err := s.Register("1", "localhost:4001", "localhost:4002")
@ -82,12 +82,8 @@ func Test_RegisterNonVoter(t *testing.T) {
return false, nil
}
c := &mockStore{
isVoterFn: func() (bool, error) {
return false, nil
},
}
s := NewService(m, c)
c := &mockStore{}
s := NewService(m, c, NonVoter)
s.RegisterInterval = 10 * time.Millisecond
ok, addr, err := s.Register("1", "localhost:4001", "localhost:4002")
@ -120,7 +116,7 @@ func Test_StartReportingTimer(t *testing.T) {
return true
}
s := NewService(m, c)
s := NewService(m, c, Voter)
s.ReportInterval = 10 * time.Millisecond
go s.StartReporting("1", "localhost:4001", "localhost:4002")
@ -147,7 +143,7 @@ func Test_StartReportingChange(t *testing.T) {
}
wg.Add(1)
s := NewService(m, c)
s := NewService(m, c, Voter)
s.ReportInterval = 10 * time.Minute // Nothing will happen due to timer.
done := s.StartReporting("1", "localhost:4001", "localhost:4002")
@ -190,7 +186,6 @@ func (m *mockClient) String() string {
type mockStore struct {
isLeaderFn func() bool
isVoterFn func() (bool, error)
registerLeaderChangeFn func(c chan<- struct{})
}
@ -201,13 +196,6 @@ func (m *mockStore) IsLeader() bool {
return false
}
func (m *mockStore) IsVoter() (bool, error) {
if m.isVoterFn != nil {
return m.isVoterFn()
}
return true, nil
}
func (m *mockStore) RegisterLeaderChange(c chan<- struct{}) {
if m.registerLeaderChangeFn != nil {
m.registerLeaderChangeFn(c)

Loading…
Cancel
Save