Documentation ¶
Overview ¶
Package leader provides a simple leader election implementation.
Introduction ¶
Leader election is particularly useful if the state cannot be rule out of your application. For example, you want to run some cron jobs to scan the database, but you have more than one instances up and running. Running cron jobs on all instances many not be desired. With the help of package leader, you can opt to only run such jobs on the leader node. When the leader goes down, a new leader will be elected. The cron job runner is therefore highly available.
Usage ¶
The package leader exports configuration in this format:
leader: etcdName: default
To use package leader with package core:
var c *core.C = core.Default() c.Provide(otetcd.Providers) // to provide the underlying driver c.Provide(leader.Providers) c.Invoke(func(status *leader.Status) { if ! status.IsLeader { return } // DO SOMETHING ON LEADER })
Example (Cronjob) ¶
package main import ( "context" "fmt" "github.com/DoNewsCode/core" "github.com/DoNewsCode/core/di" "github.com/DoNewsCode/core/leader" "github.com/DoNewsCode/core/otetcd" "github.com/robfig/cron/v3" ) type CronModule struct { Sts *leader.Status } func (s CronModule) ProvideCron(crontab *cron.Cron) { crontab.AddFunc("* * * * * *", func() { if s.Sts.IsLeader() { fmt.Println("do work as leader") } }) } func main() { c := core.Default(core.WithInline("log.level", "none")) c.Provide(di.Deps{func() *cron.Cron { return cron.New(cron.WithSeconds()) }}) c.Provide(otetcd.Providers()) c.Provide(leader.Providers()) c.Invoke(func(sts *leader.Status) { c.AddModule(CronModule{Sts: sts}) }) c.Serve(context.Background()) }
Output:
Example (Server) ¶
package main import ( "context" "fmt" "net/http" "time" "github.com/DoNewsCode/core" "github.com/DoNewsCode/core/contract" "github.com/DoNewsCode/core/events" "github.com/DoNewsCode/core/leader" "github.com/DoNewsCode/core/otetcd" "github.com/gorilla/mux" ) type ServerModule struct { Sts *leader.Status } func (s ServerModule) ProvideHTTP(router *mux.Router) { router.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { if s.Sts.IsLeader() { writer.Write([]byte("I am leader")) } else { writer.Write([]byte("I am follower")) } }) } func main() { c := core.Default(core.WithInline("log.level", "none")) c.Provide(otetcd.Providers()) c.Provide(leader.Providers()) c.Invoke(func(dispatcher contract.Dispatcher) { // This listener will be called twice. Once on becoming the leader and once on resigning the leader. dispatcher.Subscribe(events.Listen(events.From(&leader.Status{}), func(ctx context.Context, event contract.Event) error { fmt.Println(event.Data().(*leader.Status).IsLeader()) return nil })) }) c.Invoke(func(sts *leader.Status) { c.AddModule(ServerModule{Sts: sts}) }) ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() c.Serve(ctx) }
Output: true false
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNotALeader = errors.New("not a leader")
ErrNotALeader is an error triggered when Resign is called but the current node is not leader.
Functions ¶
Types ¶
type Driver ¶
type Driver interface { // Campaign starts a leader election. It should block until elected or context canceled. Campaign(ctx context.Context) error // Resign makes the current node a follower. Resign(context.Context) error }
Driver models a external storage that can be used for leader election.
type Election ¶
type Election struct {
// contains filtered or unexported fields
}
Election is a struct that controls the leader election. Whenever the leader status changed on this node, an event will be triggered. See example for how to listen this event.
func NewElection ¶
func NewElection(dispatcher contract.Dispatcher, driver Driver) *Election
NewElection returns a pointer to the newly constructed Election instance.
func (*Election) Campaign ¶
Campaign starts a leader election. It will block until this node becomes a leader or context cancelled.
Directories ¶
Path | Synopsis |
---|---|
Package leaderetcd provides a etcd driver for package leader
|
Package leaderetcd provides a etcd driver for package leader |
Package leaderredis provides a redis driver for package leader
|
Package leaderredis provides a redis driver for package leader |