Documentation ¶
Overview ¶
Package pir is a simple library for facilitating device discovery on a LAN.
The simplest way to use Pir is to:
- Start a healthcheck server healthcheck := pir.NewHealthCheck() healthcheck.Start()
- Create a new peer peer, _ := pir.NewPeer("tcp://10.1.1.1:80", healthcheck.URISpec())
- Join a group group := pir.NewGroup(group, 9999) peer.Join(group)
For the full source, see: https://github.com/jerluc/pir
Index ¶
- Constants
- func GetLocalIP() (string, error)
- func NewHealthChecker(peer *Peer) func() bool
- func ResolveURISpec(uriSpecStr string) (net.Addr, error)
- type CannotFindIPErr
- type Group
- type HealthCheck
- type HealthCheckListenTimeoutErr
- type InvalidPeerBroadcastErr
- type MembershipEvent
- type MembershipEventType
- type MembershipListener
- type Peer
- type Tracker
- type UnsupportedURISpecErr
Constants ¶
const ( // The default multicast broadcast address DefaultBroadcastIP = "224.0.0.1" // The default broadcast interval DefaultBroadcastInterval = 1 * time.Second )
const ( // The timeout duration after attempting to create a healthcheck server after // which to fail HealthCheckListenTimeout = 2 * time.Second // The TCP buffer size for healthcheck reads/writes HealthCheckBufferSize = 1 // The payload to send and receive from the healthcheck HealthCheckPayload = byte(0) )
const ( // The time interval between healthchecks HealthCheckInterval = 2 * time.Second // How long to wait on a healthcheck before timing out HealthCheckTimeout = 2 * time.Second // The failure threshold for reaping a peer ReaperThreshold = 3 )
const (
// Buffer size to use for UDP broadcasts (read/write)
UDPBufferSize = 8192
)
Variables ¶
This section is empty.
Functions ¶
func GetLocalIP ¶
GetLocalIP gets this host's local IP address for the first non-loopback IPv4 network interface. This was adapted from http://stackoverflow.com/a/31551220
func NewHealthChecker ¶
NewHealthChecker acts as a healthchecking function for a Tracker, by using the builtin healthchecking protocol to query for peer health.
Types ¶
type CannotFindIPErr ¶
type CannotFindIPErr struct{}
func (CannotFindIPErr) Error ¶
func (c CannotFindIPErr) Error() string
type Group ¶
type Group struct { // The group's textual name Name string // The multicast broadcast address to use for membership broadcasts BroadcastAddress *net.UDPAddr // The broadcast interval between broadcasts BroadcastInterval time.Duration // contains filtered or unexported fields }
A Group represents the current host's logical representation of a LAN-based peer network, including keeping track of peer membership.
func NewGroup ¶
NewGroup creates a new group with the given name, listening on the given multicast broadcast port
func (*Group) AddListener ¶
func (g *Group) AddListener(listener MembershipListener)
Adds a MembershipListener to the list of listeners to be notified of group membership events
func (*Group) AddPeer ¶
AddPeer adds a peer to the group's membership list, if it doesn't already exist. To add the peer, a new tracker is first created for the peer and started, then the membershipListeners are notified of the PeerAdded event.
func (*Group) RemovePeer ¶
RemovePeer removes a peer from the group's membership list, if it exists, and notifies each of the membershipListeners of the PeerRemoved event. Note that since this typically occurs in response to peer death, the call to kill the corresponding peer tracker will normally be a no-op. However, in the case that RemovePeer is called from an outside client, the call to kill the peer tracker will have side-effects.
type HealthCheck ¶
type HealthCheck struct {
// contains filtered or unexported fields
}
A HealthCheck acts as a server to handle the health-checking protocol
func (*HealthCheck) Start ¶
func (h *HealthCheck) Start() error
Start asynchronously starts listening on the next available port, handling the builtin healthcheck protocol.
func (*HealthCheck) URISpec ¶
func (h *HealthCheck) URISpec() string
URISpec is a convenience method to construct the URI specification for this healthcheck server
type HealthCheckListenTimeoutErr ¶
type HealthCheckListenTimeoutErr struct{}
A HealthCheckListenTimeoutErr occurs when the healthcheck server fails to start after the HealthCheckListenTimeout elapses
func (HealthCheckListenTimeoutErr) Error ¶
func (h HealthCheckListenTimeoutErr) Error() string
type InvalidPeerBroadcastErr ¶
type InvalidPeerBroadcastErr struct {
// contains filtered or unexported fields
}
An InvalidPeerBroadcastErr occurs when a broadcast payload cannot be interpreted. This typically isn't fatal, but can be a sign of a broken or outdated protocol implementation.
func (InvalidPeerBroadcastErr) Error ¶
func (i InvalidPeerBroadcastErr) Error() string
type MembershipEvent ¶
type MembershipEvent struct { // The group in which the membership change occurred Group *Group // The peer that changed Peer *Peer // The kind of membership change that occurred Type MembershipEventType }
A MembershipEvent contains metadata about a change in group membership
func (MembershipEvent) String ¶
func (m MembershipEvent) String() string
type MembershipEventType ¶
type MembershipEventType string
A kind of membership event
const ( // PeerAdded occurs when a new peer is added to a group PeerAdded MembershipEventType = "peer-added" // PeerRemoved occurs when an existing peer is removed from a group PeerRemoved = "peer-removed" )
type MembershipListener ¶
type MembershipListener func(MembershipEvent) bool
A MembershipListener is a function which is fired when a membership change occurs in a given group. To continue receiving future updates, the MembershipListener should return true; returning false indicates that this listener no longer wishes to receive updates.
type Peer ¶
type Peer struct { // UUID4 to identify this peer uniquely; should be unique even across multiple // groups. If this ID is stable/reproducible, group membership will also be // stable/reproducible. ID string // The communications URI specification; Pir does not interpret the meaning of // this URI itself, as this URI is application/service specific CommsSpec *url.URL // The healthcheck URI specification; this URI is used by Pir to maintain // logical group membership, as viewed by the local Peer instance HealthCheckSpec *url.URL }
A Peer is a logical representation of a peering device participating in a group. This same representation is used both for remote and local peers, for simplicity and consistency.
func NewPeer ¶
NewPeer creates a new peer from the provided communications and healthcheck URIs. If either URI is invalid, an error is returned.
func (*Peer) Advertise ¶
Advertise advertises this peer on the given group during each broadcast interval using the group's broadcast address. The advertising packet is formatted as: `GROUP_NAME|UUID4|proto://x.x.x.x:xxxxx|proto://x.x.x.x:xxxxx`
type Tracker ¶
type Tracker struct {
// contains filtered or unexported fields
}
A Tracker is responsible for keeping track of the health status for a given peer.
func NewTracker ¶
NewTracker creates a Tracker instance
func (*Tracker) IsAlive ¶
IsAlive queries for peer health. If a value is waiting on the deathChan, IsAlive instantly fails. Otherwise, either the healthCheck function returns in the given time, determining peer health, or a subsequent timeout is surpassed, causing health degradation. Finally, if the unhealthyCount surpasses the ReaperThreshold, IsAlive fails.
func (*Tracker) Kill ¶
func (t *Tracker) Kill()
Kill triggers instant death of the peer tracker by sending a poison pill onto the death channel
func (*Tracker) MarkHealthy ¶
func (t *Tracker) MarkHealthy()
MarkHealthy linearly forgives previous healthcheck failures (but cannot) repair beyond zero.
func (*Tracker) MarkUnhealthy ¶
func (t *Tracker) MarkUnhealthy()
MarkUnhealthy linearly degrades with peer health
type UnsupportedURISpecErr ¶
type UnsupportedURISpecErr struct {
// contains filtered or unexported fields
}
An UnsupportedURISpecErr occurs when the URI specification uses an unknown scheme (concretely, this is any scheme outside of "tcp" or "udp").
func (UnsupportedURISpecErr) Error ¶
func (u UnsupportedURISpecErr) Error() string