func (e *Election) Campaign(ctx context.Context) error {
	if err := e.driver.Campaign(ctx); err != nil {
		return fmt.Errorf("not elected: %w", err)
	}
	e.status.isLeader.Store(true)
	e.dispatcher.Dispatch(ctx, OnStatusChanged, OnStatusChangedPayload{Status: e.status})
	return nil
}
Campaign starts a leader election. It will block until this node becomes a leader or context cancelled.
package leader
import (
	"context"
	"errors"
	"fmt"
	"github.com/DoNewsCode/core/contract"
	"go.uber.org/atomic"
)
var ErrNotALeader = errors.New("not a leader")
type Driver interface {
	Campaign(ctx context.Context) error
	Resign(context.Context) error
}
type Election struct {
	dispatcher contract.Dispatcher
	status     *Status
	driver     Driver
}
func NewElection(dispatcher contract.Dispatcher, driver Driver) *Election {
	return &Election{
		dispatcher: dispatcher,
		status:     &Status{isLeader: &atomic.Bool{}},
		driver:     driver,
	}
}