Documentation ¶
Overview ¶
Proxy-Seeking alogirthm
Premise: An unknown number of proxies exist behind a "fair" load-balancer. Proxies will share their peerset via gossip, but this gossip is asynchronous and may suffer from ordering/timing issues. Furthermore, rotations may cause a complete and permanent loss of contact with all known proxies.
Goals: Ensure that we have one agent managing a connection to each available proxy. Minimize unnecessary discovery attempts. Recover from bad state (e.g. due to full rotations) in a timely manner. Mitigate resource drain due to failing or unreachable proxies.
Each known proxy has an associated entry which stores its seek state (seeking | claimed | backoff).
When an agent discovers (connects to) a proxy, it attempts to acquire an exclusive claim to that proxy. If sucessful, the agent takes responsibility for the proxy, releasing its claim when the connection terminates (regardless of reason). If another agent has already claimed the proxy, the connection is dropped.
Unclaimed entries are subject to expiry. Expiration timers are refreshed by gossip messages.
If a claim is released within a very short interval after being acquired, termination is said to be premature. Premature termination triggers a backoff phase which pauses discovery attempts for the proxy. The length of the backoff phase is determined by an incrementing multiplier. If backoff is entered too often to allow the counter to reset, the backoff phase will grow beyond the expiry limit and the associated entry will be removed.
+---------+ | | acquire | START +------------------------------------------------+ | | | +----+----+ v | +-----+-----+ | refresh release (ok) | | +-----+--------+ +----------------------------+ Claimed | ^ | | | | | v v +--+-----+--+ | +---+---+---+ ^ | | | | acquire | | +----+ Seeking +---------------------------+ | | | | +--------+ +---+---+---+ | | | | ^ +-----------+ | | STOP | | | done | | release (err) | | | | +--------+ Backoff +<---------------+ +---+----+ | | | ^ | +-----+-----+ | v expire | +---------------+------------------+
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { // TickRate defines the maximum amount of time between expiry & seek checks. // Shorter tick rates reduce discovery delay. Longer tick rates reduce resource // consumption (default: ~4s). TickRate time.Duration // EntryExpiry defines how long a seeker entry should be held without successfully // establishing a healthy connection. This value should be reasonably long // (default: 3m). EntryExpiry time.Duration // BackoffInterval defines the basline backoff amount observed by seekers. This value // should be reasonably short (default: 256ms) BackoffInterval time.Duration // BackoffThreshold defines the minimum amount of time that a connection is expected to last // if the conencted peer is generally healthy. Connections which fail before BackoffThreshold // cause the seekstate to enter backoff (default: 30s) BackoffThreshold time.Duration }
Config describes the various parameters related to a seek operation
func (*Config) CheckAndSetDefaults ¶
type GroupHandle ¶
type GroupHandle struct {
// contains filtered or unexported fields
}
GroupHandle is a handle to an ongoing seek process. Each seek process manages a group of related proxies. This handle allows agents to claim exclusive "locks" for individual proxies and to broadcast gossip to the process.
func (*GroupHandle) Gossip ¶
func (s *GroupHandle) Gossip() chan<- string
Gossip channel must be informed whenever a proxy's identity becomes known via gossip messages.
func (*GroupHandle) Status ¶
func (s *GroupHandle) Status() <-chan Status
Status channel is regularly updated with the most recent status value. Consuming status values is optional.
func (*GroupHandle) WithProxy ¶
func (s *GroupHandle) WithProxy(do func(), principals ...string) (did bool)
WithProxy is used to wrap the connection-handling logic of an agent, ensuring that it is run if and only if no other agent is already handling this proxy.
type Pool ¶
type Pool struct {
// contains filtered or unexported fields
}
Pool manages a collection of group-level seek operations.
func (*Pool) Group ¶
func (p *Pool) Group(key Key) GroupHandle
Group gets a handle to the seek manager for the specified group. If none exists, one will be started.
type Status ¶
Status is a summary of the status of a collection of proxy seek states.
func (*Status) ShouldSeek ¶
ShouldSeek checks if we should be seeking connections.