Documentation ¶
Index ¶
- Variables
- func EncPkt(incarnation uint16, message Message) []byte
- type AddressKind
- type Alive
- func (a *Alive) Encode(into []byte)
- func (a *Alive) FromNode(n *Node)
- func (a *Alive) GetIncarnation() uint16
- func (a *Alive) GetSubject() IP
- func (a *Alive) Invalidates(current *Event) bool
- func (a *Alive) Kind() EventKind
- func (a *Alive) RequiredSize() int
- func (a *Alive) SourceAddressKind() AddressKind
- func (a *Alive) SubjectAddressKind() AddressKind
- type BootstrapAck
- type BootstrapRequest
- type BootstrapResponse
- type Encoder
- type Event
- type EventEncoder
- type EventKind
- type Faulty
- func (f *Faulty) Encode(into []byte)
- func (f *Faulty) FromNode(n *Node)
- func (f *Faulty) GetIncarnation() uint16
- func (f *Faulty) GetSubject() IP
- func (f *Faulty) Invalidates(current *Event) bool
- func (f *Faulty) Kind() EventKind
- func (f *Faulty) RequiredSize() int
- func (f *Faulty) SetSource(addr *IP)
- func (f *Faulty) SourceAddressKind() AddressKind
- func (f *Faulty) SubjectAddressKind() AddressKind
- type Header
- type Healthy
- func (h *Healthy) Encode(into []byte)
- func (h *Healthy) FromNode(n *Node)
- func (h *Healthy) GetIncarnation() uint16
- func (h *Healthy) GetSubject() IP
- func (h *Healthy) Invalidates(current *Event) bool
- func (h *Healthy) Kind() EventKind
- func (h *Healthy) RequiredSize() int
- func (h *Healthy) SetSource(ip *IP)
- func (h *Healthy) SourceAddressKind() AddressKind
- func (h *Healthy) SubjectAddressKind() AddressKind
- type IP
- type IndirectPing
- type IndirectPong
- type Join
- func (j *Join) Encode(into []byte)
- func (j *Join) FromNode(n *Node)
- func (j *Join) GetIncarnation() uint16
- func (j *Join) GetSubject() IP
- func (j *Join) Invalidates(current *Event) bool
- func (j *Join) Kind() EventKind
- func (j *Join) RequiredSize() int
- func (j *Join) SetSource(addr *IP)
- func (j *Join) SourceAddressKind() AddressKind
- func (j *Join) SubjectAddressKind() AddressKind
- type Left
- func (l *Left) Encode(into []byte)
- func (l *Left) FromNode(n *Node)
- func (l *Left) GetIncarnation() uint16
- func (l *Left) GetSubject() IP
- func (l *Left) Invalidates(current *Event) bool
- func (l *Left) Kind() EventKind
- func (l *Left) RequiredSize() int
- func (l *Left) SourceAddressKind() AddressKind
- func (l *Left) SubjectAddressKind() AddressKind
- type Message
- type NoDecoderError
- type NoEventDecoderError
- type Node
- type NodeHash
- type NodeInheritor
- type OpCode
- type Packet
- type Ping
- type Pong
- type Suspect
- func (s *Suspect) Encode(into []byte)
- func (s *Suspect) FromNode(n *Node)
- func (s *Suspect) GetIncarnation() uint16
- func (s *Suspect) GetSubject() IP
- func (s *Suspect) Invalidates(current *Event) bool
- func (s *Suspect) Kind() EventKind
- func (s *Suspect) RequiredSize() int
- func (s *Suspect) SetSource(source *IP)
- func (s *Suspect) SourceAddressKind() AddressKind
- func (s *Suspect) SubjectAddressKind() AddressKind
- type Sync
- type SyncMode
- type TCPPacket
- type Wrap
- func (w *Wrap) Encode(into []byte)
- func (w *Wrap) FromNode(n *Node)
- func (w *Wrap) GetIncarnation() uint16
- func (w *Wrap) GetSubject() IP
- func (w *Wrap) Invalidates(current *Event) bool
- func (w *Wrap) Kind() EventKind
- func (w *Wrap) RequiredSize() int
- func (w *Wrap) SourceAddressKind() AddressKind
- func (w *Wrap) SubjectAddressKind() AddressKind
- type Writer
Constants ¶
This section is empty.
Variables ¶
var CouldNotParsePacketErr = fmt.Errorf("could not parse data")
CouldNotParsePacketErr indicates that a parsing operation could not yield a valid result from the provided data buffer.
var NodeHashZero = NodeHash{}
var PacketDecoder = fsm.Def[Packet, packetDecoderState, packetDecoderContext]{ Feed: func(f *fsm.FSM[Packet, packetDecoderState, packetDecoderContext], state packetDecoderState, ctx *packetDecoderContext, b byte) error { switch state { case packetDecoderStateHeader: head, err := ctx.headerDecoder.Feed(b) if err != nil { return err } if head != nil { decoder, ok := messageDecoderList[head.OpCode] if !ok { return NoDecoderError{op: head.OpCode} } f.Value.Header = *head if decoder == nil { t, ok := emptyMessageTypes[f.Value.Header.OpCode] if ok { f.Value.Message = reflect.New(t).Interface().(Message) } return fsm.Done } ctx.payloadDecoder = decoder.NewGeneric() f.Transition(packetDecoderStatePayload) } case packetDecoderStatePayload: msg, err := ctx.payloadDecoder.FeedAny(b) if err != nil { return err } if msg != nil { f.Value.Message = msg.(Message) return fsm.Done } } return nil }, }
var TCPPacketDecoder = fsm.Def[TCPPacket, tcpPacketDecoderState, struct{}]{ InitialSize: 2, Feed: func(f *fsm.FSM[TCPPacket, tcpPacketDecoderState, struct{}], state tcpPacketDecoderState, ctx *struct{}, b byte) error { switch state { case tcpPacketDecoderStateMagic: if f.U16() != protocolMagic { f.Reset() return nil } f.Value.Magic = protocolMagic f.TransitionSatisfySize(tcpPacketDecoderStateVersion, 1) case tcpPacketDecoderStateVersion: if b != 1 { f.Reset() return nil } f.Value.Version = b f.TransitionSatisfySize(tcpPacketDecoderStateSize, 4) case tcpPacketDecoderStateSize: f.Value.Payload = make([]byte, f.U32()) f.TransitionSatisfySize(tcpPacketDecoderStatePayload, len(f.Value.Payload)) case tcpPacketDecoderStatePayload: f.CopyPayload(f.Value.Payload) return fsm.Done } return nil }, }.IntoExported()
TCPPacketDecoder is responsible for decoding a TCP stream into TCPPacket(s)
Functions ¶
Types ¶
type AddressKind ¶
type AddressKind uint8
AddressKind indicates which kind of address is contained within a message or substructure
const ( AddressIPv4 AddressKind = 0 AddressIPv6 AddressKind = 1 )
func (AddressKind) Size ¶
func (a AddressKind) Size() int
Size returns the amount of bytes required to represent this AddressKind
func (AddressKind) String ¶
func (i AddressKind) String() string
func (AddressKind) UnixProto ¶
func (a AddressKind) UnixProto() int
UnixProto returns the Unix syscall value representing the current AddressKind
type Alive ¶
Alive represents the value of an EventAlive event. It refutes a Suspect event, given that { Alive.Incarnation=j, Suspect.Incarnation=i }, j > i.
func (*Alive) GetIncarnation ¶
func (*Alive) GetSubject ¶
func (*Alive) Invalidates ¶
func (*Alive) RequiredSize ¶
func (*Alive) SourceAddressKind ¶
func (a *Alive) SourceAddressKind() AddressKind
func (*Alive) SubjectAddressKind ¶
func (a *Alive) SubjectAddressKind() AddressKind
type BootstrapAck ¶
type BootstrapAck struct{}
BootstrapAck represents a response for a BootstrapResponse, and contains no fields. This message is emitted to the control socket of a node to indicate that the bootstrap process can now proceed through the TCP channel. This is required to prevent multiple bootstrap responders to try to connect to the same node requesting bootstrap.
func (BootstrapAck) Encode ¶
func (BootstrapAck) Encode([]byte)
func (BootstrapAck) OpCode ¶
func (BootstrapAck) OpCode() OpCode
func (BootstrapAck) RequiredSize ¶
func (BootstrapAck) RequiredSize() int
type BootstrapRequest ¶
type BootstrapRequest struct{}
BootstrapRequest represents a bootstrap message emitted in a multicast network. Other nodes listening to the same network may respond to this message by emitting a UDP Unicast BootstrapResponse.
func (BootstrapRequest) Encode ¶
func (BootstrapRequest) Encode([]byte)
func (BootstrapRequest) OpCode ¶
func (BootstrapRequest) OpCode() OpCode
func (BootstrapRequest) RequiredSize ¶
func (BootstrapRequest) RequiredSize() int
type BootstrapResponse ¶
type BootstrapResponse struct{}
BootstrapResponse represents a response for a BootstrapRequest, and contains no fields. The node's address can be obtained through the Packet structure wrapping this BootstrapResponse, and the responding node's incarnation number can be obtained from Header.Incarnation, also present in the upper Packet structure.
func (BootstrapResponse) Encode ¶
func (BootstrapResponse) Encode([]byte)
func (BootstrapResponse) OpCode ¶
func (BootstrapResponse) OpCode() OpCode
func (BootstrapResponse) RequiredSize ¶
func (BootstrapResponse) RequiredSize() int
type Encoder ¶
type Encoder interface { // RequiredSize returns the amount of bytes required to encode the current // structure. RequiredSize() int // Encode takes a slice of bytes and writes the current structure's // serialized representation into it. It assumes that len(into) is equal or // greater to the value returned by RequiredSize. Encode(into []byte) }
Encoder represents any structure that can be encoded by Writer or any other decoding facility
type Event ¶
type Event struct {
Payload EventEncoder
}
Event represents a single event that occurred against a given IP.
func (Event) RequiredSize ¶
type EventEncoder ¶
type EventEncoder interface { Encoder Kind() EventKind SourceAddressKind() AddressKind SubjectAddressKind() AddressKind GetIncarnation() uint16 GetSubject() IP Invalidates(other *Event) bool }
EventEncoder represents a structure capable of encoding an Event
type EventKind ¶
type EventKind uint8
const ( // EventJoin represents an event indicating that a new member has been added // to the cluster after a known member bootstraps it. EventJoin EventKind = 0b0000 // EventHealthy indicates that a cluster member asserted a given node as // healthy, after it has been suspected as faulty. EventHealthy EventKind = 0b0001 // EventSuspect indicates that a cluster member suspects that a given node // is suspected to be faulty. EventSuspect EventKind = 0b0010 // EventFaulty indicates that a cluster member could not be reached for a // given period of time and is no longer considered a member of the current // cluster. EventFaulty EventKind = 0b0011 // EventLeft is voluntarily emitted by nodes before they leave the cluster, // potentially avoiding a whole suspect->indirect ping->faulty check by // other cluster members. EventLeft EventKind = 0b0100 // EventAlive is emitted by nodes that noticed their healthiness was being // suspected, in order to indicate that it is actually running and able to // be part of the cluster. EventAlive EventKind = 0b0101 // EventWrap is emitted by nodes to indicate that their incarnation count // will wrap back to zero after exhausting other uint16 values. EventWrap EventKind = 0b0110 )
type Faulty ¶
Faulty represents the value of an EventFaulty, and indicates that Source assumed { Subject, inc=Incarnation } as faulty due to lack of response and failure to receive responses from indirect pings.
func (*Faulty) GetIncarnation ¶
func (*Faulty) GetSubject ¶
func (*Faulty) Invalidates ¶
func (*Faulty) RequiredSize ¶
func (*Faulty) SourceAddressKind ¶
func (f *Faulty) SourceAddressKind() AddressKind
func (*Faulty) SubjectAddressKind ¶
func (f *Faulty) SubjectAddressKind() AddressKind
type Header ¶
Header is a structure present in every exchanged message. It contains the protocol magic bytes, the version to which the message belongs to, the message type, and the incarnation identifier of the member that emitted this it.
func (Header) RequiredSize ¶
type Healthy ¶
Healthy represents the value of an EventHealthy and indicates that Source assumed { Subject, inc=Incarnation } as healthy, after a protocol period.
func (*Healthy) GetIncarnation ¶
func (*Healthy) GetSubject ¶
func (*Healthy) Invalidates ¶
func (*Healthy) RequiredSize ¶
func (*Healthy) SourceAddressKind ¶
func (h *Healthy) SourceAddressKind() AddressKind
func (*Healthy) SubjectAddressKind ¶
func (h *Healthy) SubjectAddressKind() AddressKind
type IP ¶
type IP struct { AddressKind AddressKind AddressBytes [16]byte }
IP stores an AddressKind along with the bytes comprising it
func IPFromAddr ¶
IPFromAddr returns a new IP from a given netip.Addr structure.
func IPFromNetIP ¶
IPFromNetIP returns a new IP from a given net.IP structure.
func (IP) IntoManaged ¶
IntoManaged returns the net.IP representation for the current IP
type IndirectPing ¶
type IndirectPing struct { // Cookie is a random value generated by the requester to identify this ping // request. It must be relayed back as is to it. Cookie uint16 // Period represents the protocol period in which the host was when sending // this request. It must be relayed back as is to it. Period uint16 // Address represents the address to perform a ping against. Address IP }
IndirectPing represents a request sent by a member suspecting that another member is faulty.
func (IndirectPing) Encode ¶
func (i IndirectPing) Encode(into []byte)
func (IndirectPing) OpCode ¶
func (i IndirectPing) OpCode() OpCode
func (IndirectPing) RequiredSize ¶
func (i IndirectPing) RequiredSize() int
type IndirectPong ¶
IndirectPong represents a response for a IndirectPing
func (IndirectPong) Encode ¶
func (i IndirectPong) Encode(into []byte)
func (IndirectPong) OpCode ¶
func (i IndirectPong) OpCode() OpCode
func (IndirectPong) RequiredSize ¶
func (i IndirectPong) RequiredSize() int
type Join ¶
Join represents the value of an EventJoin, and indicates that a node Source has allowed{ Subject, inc = Incarnation } to join the current cluster.
func (*Join) GetIncarnation ¶
func (*Join) GetSubject ¶
func (*Join) Invalidates ¶
func (*Join) RequiredSize ¶
func (*Join) SourceAddressKind ¶
func (j *Join) SourceAddressKind() AddressKind
func (*Join) SubjectAddressKind ¶
func (j *Join) SubjectAddressKind() AddressKind
type Left ¶
Left represents the value of an EventLeft, and indicates that a given node Subject intends to leave the cluster immediately. This prevents other nodes from wasting resources trying to reach a node that left a cluster in a graceful manner.
func (*Left) GetIncarnation ¶
func (*Left) GetSubject ¶
func (*Left) Invalidates ¶
func (*Left) RequiredSize ¶
func (*Left) SourceAddressKind ¶
func (l *Left) SourceAddressKind() AddressKind
func (*Left) SubjectAddressKind ¶
func (l *Left) SubjectAddressKind() AddressKind
type NoDecoderError ¶
type NoDecoderError struct {
// contains filtered or unexported fields
}
NoDecoderError indicates that this library does not have a decoder for a given received message.
func (NoDecoderError) Error ¶
func (n NoDecoderError) Error() string
type NoEventDecoderError ¶
type NoEventDecoderError struct {
DecoderID uint8
}
NoEventDecoderError indicates that this library does not have a decoder for given received event.
func (NoEventDecoderError) Error ¶
func (n NoEventDecoderError) Error() string
type Node ¶
type Node struct { /// Suspect denotes whether a node, as perceived by the transmitting node, // is potentially in a StateFaulty condition. Suspect bool // Incarnation represents the last known incarnation ID of this node. Incarnation uint16 // Address represents the address of this member. Address IP }
Node represents a member of the cluster.
func (Node) Hash ¶
Hash returns a hashed representation of the current node's address in the form of a NodeHash
func (Node) RequiredSize ¶
type NodeHash ¶
NodeHash is a container type responsible for representing a Node unique identifier, which for our purposes, is the identity of the Node's IP address bytes.
type NodeInheritor ¶
type NodeInheritor interface {
FromNode(n *Node)
}
NodeInheritor represents a structure that can update its own values given a Node instance.
type OpCode ¶
type OpCode uint8
const ( // BTRP is a BootstrapRequest message BTRP OpCode = 0x01 // BTRR is a BootstrapResponse message BTRR OpCode = 0x02 // BTRA is a BootstrapAck message BTRA OpCode = 0x03 // PING is a Ping message PING OpCode = 0x04 // PONG is a Pong message PONG OpCode = 0x05 // IING is an IndirectPing message IING OpCode = 0x06 // IONG is an IndirectPong message IONG OpCode = 0x07 // SYNC is a FullSync message SYNC OpCode = 0x08 )
type Packet ¶
Packet contains a Header and a Message object. Additionally, Packet may contain an extra Source, representing the IP from which the message came from.
func ParsePacket ¶
ParsePacket attempts to parse a provided data byte slice into a Packet structure, including its payload. Returns an error in case the operation does not yield a valid Packet.
func (Packet) RequiredSize ¶
type Ping ¶
type Ping struct { // Cookie represents a random value representing this ping request Cookie uint16 // Period represents the current protocol period in the member that // generated this message. Period uint16 // TargetIncarnation indicates the known incarnation of the node being // pinged in the current view of the local node TargetIncarnation uint16 // Events contains a list of events observed by the node sending this ping. Events []Event }
Ping represents a ping request to another cluster member.
func (Ping) RequiredSize ¶
type Pong ¶
type Pong struct { // Ack indicates whether the target node accepted the ping payload. When set // to false, this indicates that the provided Ping.TargetIncarnation did not // correspond to the current node's incarnation, and was therefore ignored. // This is used to avoid nodes announcing suspects due to their own view // being outdated. Ack bool Cookie, Period uint16 IsLastStateKnown bool LastKnownEventKind EventKind LastKnownIncarnation uint16 }
Pong represents a response for a Ping message.
func (Pong) RequiredSize ¶
type Suspect ¶
Suspect represents the value of an EventSuspect, which indicates that a node Source could not reach a second node Subject, and started indirect Ping attempts.
func (*Suspect) GetIncarnation ¶
func (*Suspect) GetSubject ¶
func (*Suspect) Invalidates ¶
func (*Suspect) RequiredSize ¶
func (*Suspect) SourceAddressKind ¶
func (s *Suspect) SourceAddressKind() AddressKind
func (*Suspect) SubjectAddressKind ¶
func (s *Suspect) SubjectAddressKind() AddressKind
type Sync ¶
Sync represents a Sync request for another node. It contains all Node objects known by this (or the other) member.
func (Sync) RequiredSize ¶
type TCPPacket ¶
TCPPacket represents an opaque TCP message of an arbitrary length. This packet is a mere convenience to retain all parsing operations isolated in the networking package.
func EncTCPPkt ¶
func EncTCPPkt(incarnation uint16, message Message, cryptoSealer func([]byte) ([]byte, error)) (*TCPPacket, error)
EncTCPPkt encodes a given Message into a TCPPacket, sealing it using the provided `cryptoSealer`. `incarnation` and `message` are handled verbatim by EncPkt before sealing.
func (TCPPacket) RequiredSize ¶
type Wrap ¶
Wrap represents the value of an EventWrap. It indicates that a given node Subject is about to have its incarnation number wrapped to a previous value, as a new interaction would overflow the size of the current numeric type.
func (*Wrap) GetIncarnation ¶
func (*Wrap) GetSubject ¶
func (*Wrap) Invalidates ¶
func (*Wrap) RequiredSize ¶
func (*Wrap) SourceAddressKind ¶
func (w *Wrap) SourceAddressKind() AddressKind
func (*Wrap) SubjectAddressKind ¶
func (w *Wrap) SubjectAddressKind() AddressKind
Source Files ¶
- addresskind_string.go
- base.go
- error.go
- event.go
- event_alive.go
- event_faulty.go
- event_healthy.go
- event_join.go
- event_left.go
- event_suspect.go
- event_wrap.go
- eventkind_string.go
- header.go
- invalidation.go
- message_bootstrap_ack.go
- message_bootstrap_request.go
- message_bootstrap_response.go
- message_indirect_ping.go
- message_indirect_pong.go
- message_ping.go
- message_pong.go
- message_sync.go
- node.go
- opcode_string.go
- packet.go
- syncmode_string.go
- tcp_packet.go
- writer.go