# README
cluster
Package cluster provides code to manage cluster Membership. Membership can currently be managed statically (via explicit configuration of active) or dynamically (using HashiCorp's Serf project).
import go.pitz.tech/lib/cluster
Usage
type CancelWatch
type CancelWatch func()
CancelWatch is used to remove a watch from the cluster membership.
type Cluster
type Cluster struct {
}
Cluster handles the discovery and management of cluster members. It uses HashiCorp's Serf and MemberList projects to discover and track active given a join address.
func New
func New(opts ...Option) *Cluster
New constructs a cluster given the provided options.
func (*Cluster) Membership
func (c *Cluster) Membership() *Membership
Membership returns the underlying membership of the cluster. Useful for obtaining a snapshot or for manipulating the entries used by the cluster during testing.
func (*Cluster) Start
func (c *Cluster) Start(ctx context.Context) error
Start initializes and starts up the cluster.
type Config
type Config struct {
NoDiscovery
DNSDiscovery
GossipDiscovery
}
Config provides a common configuration structure for forming clusters. This can be done by specifying a concrete list of peers, a DNS name that's periodically resolved, or using a gossip protocol.
func (*Config) Start
func (c *Config) Start(ctx context.Context, membership *Membership) error
Start controls which discovery mechanism is invoked based on the provided configuration.
type DNSDiscovery
type DNSDiscovery struct {
Name string `json:"dns_name" usage:"specify the dns name to resolve"`
ResolveInterval time.Duration `json:"dns_resolve_interval" usage:"how frequently the dns name should be resolved" default:"30s"`
}
DNSDiscovery uses DNS to resolve cluster membership. Currently, this implementation uses the default DNS resolver that comes with Go. I know that the serf library uses something beyond the default implementation, so it might be worth exploring this later on.
func (*DNSDiscovery) Start
func (dns *DNSDiscovery) Start(ctx context.Context, membership *Membership) error
type Discovery
type Discovery interface {
// Start runs the discovery process. Implementations should block, regardless if they're filling or subscribing to
// the membership pool.
Start(ctx context.Context, membership *Membership) error
}
Discovery provides an abstraction that allows implementers to fill or discover changes to the underlying membership pool. For example, GossipDiscovery fills the membership pool with members found via HashiCorp's Serf implementation. The leaderless.Director package implements this interface to learn about changes in the underlying membership pool.
type GossipDiscovery
type GossipDiscovery struct {
JoinAddress string `json:"join_address" usage:"create a cluster dynamically through a single join address"`
Config *serf.Config `json:"-"`
}
GossipDiscovery uses HashiCorp's Serf library to discover nodes within the cluster. It requires both TCP and UDP communication to be available.
func (*GossipDiscovery) Start
func (g *GossipDiscovery) Start(ctx context.Context, membership *Membership) error
type Membership
type Membership struct {
}
Membership tacks a current list of active within the cluster. It can be populated manually (useful for testing) or using common discovery mechanisms.
func (*Membership) Add
func (m *Membership) Add(peers []string)
Add inserts the provided active into the cluster's active list. Operation should
be O( m log(n) )
where m = len(peers)
and n = len(m.active) + len(m.left)
.
func (*Membership) Left
func (m *Membership) Left(peers []string)
Left allows peers to temporarily leave the cluster, but still be considered part
of active membership. Operation should be O( m log(n) )
where m = len(peers)
and n = len(m.active) + len(m.left)
.
func (*Membership) Majority
func (m *Membership) Majority() int
Majority computes a cluster majority. This returns a simple majority for the cluster.
func (*Membership) Remove
func (m *Membership) Remove(peers []string)
Remove deletes the provided active from the cluster's peer list. Operation
should be O( m log(n) )
where m = len(peers)
and n = len(m.active) + len(m.left)
.
func (*Membership) Snapshot
func (m *Membership) Snapshot() ([]string, int)
Snapshot returns a copy of the current peer list.
func (*Membership) Watch
func (m *Membership) Watch() (<-chan MembershipChange, CancelWatch)
Watch allows others to observe changes in the cluster membership.
type MembershipChange
type MembershipChange struct {
Active []string
Left []string
Removed []string
}
MembershipChange describes how the cluster membership has changed to outside observers.
type NoDiscovery
type NoDiscovery struct {
Peers []string `json:"peers" usage:"create a cluster using a static list of addresses"`
}
NoDiscovery uses a statically provided list of peers to fill Membership.
func (*NoDiscovery) Start
func (n *NoDiscovery) Start(ctx context.Context, membership *Membership) error
type Option
type Option func(cluster *Cluster)
Option defines how callers can customize aspects of the cluster.
func WithDiscovery
func WithDiscovery(discovery Discovery) Option
WithDiscovery allows alternative peer discovery mechanisms to be plugged in.