election

package
v3.0.0+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2019 License: Apache-2.0 Imports: 8 Imported by: 0

README

ETCD Leader Election

Use etcd for leader election if you have several instances of a service running in production and you only want one of the service instances to preform a task.

LeaderElection starts a goroutine which performs an election and maintains a leader while services join and leave the election. Calling Stop() will Concede() leadership if we currently have it.


import (
    "github.com/mailgun/holster"
    "github.com/mailgun/holster/election"
)

var wg holster.WaitGroup

// Start the goroutine and preform the election
leader, _ := election.New(election.Config{
    Endpoints:     []string{"http://192.168.99.100:2379"},
    Name: "my-service"
})

// Handle graceful shutdown
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt, os.Kill)

// Do periodic thing
tick := time.NewTicker(time.Second * 2)
wg.Loop(func() bool {
    select {
    case <-tick.C:
        // Are we currently leader?
        if leader.IsLeader() {
            err := DoThing()
            if err != nil {
                // Have another instance DoThing(), we can't for some reason
                leader.Concede()
            }
        }
        return true
    case <-signalChan:
        leader.Stop()
        return false
    }
})
wg.Wait()

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// The name of the election (IE: scout, blackbird, etc...)
	Election string
	// The name of this instance (IE: worker-n01, worker-n02, etc...)
	Candidate string

	Endpoints []string
	TTL       time.Duration
}

type EtcdElection

type EtcdElection struct {
	// contains filtered or unexported fields
}

func New

func New(conf Config) (*EtcdElection, error)

Use leader election if you have several instances of a service running in production and you only want one of the service instances to preform a periodic task.

	election, _ := election.New(election.Config{
		Endpoints:     []string{"http://192.168.99.100:2379"},
	})

 // Start the leader election and attempt to become leader
 election.Start()

	// Returns true if we are leader (thread safe)
	if election.IsLeader() {
		// Do periodic thing
	}

func NewFromClient

func NewFromClient(conf Config, client etcd.Client) (*EtcdElection, error)

func (*EtcdElection) Concede

func (s *EtcdElection) Concede() bool

Release leadership and return true if we own it, else do nothing and return false

func (*EtcdElection) IsLeader

func (s *EtcdElection) IsLeader() bool

func (*EtcdElection) Start

func (s *EtcdElection) Start()

func (*EtcdElection) Stop

func (s *EtcdElection) Stop()

func (*EtcdElection) Watch

func (s *EtcdElection) Watch(ctx context.Context, startIndex uint64) chan bool

Watch the prefix for any events and send a 'true' if we should attempt grab leader

type LeaderElectionMock

type LeaderElectionMock struct{}

func (*LeaderElectionMock) Concede

func (s *LeaderElectionMock) Concede() bool

func (*LeaderElectionMock) IsLeader

func (s *LeaderElectionMock) IsLeader() bool

func (*LeaderElectionMock) Start

func (s *LeaderElectionMock) Start()

func (*LeaderElectionMock) Stop

func (s *LeaderElectionMock) Stop()

func (*LeaderElectionMock) Watch

func (s *LeaderElectionMock) Watch(ctx context.Context, startIndex uint64) chan bool

type LeaderElector

type LeaderElector interface {
	Watch(context.Context, uint64) chan bool
	IsLeader() bool
	Concede() bool
	Start()
	Stop()
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL