109 lines
2.5 KiB
Go
109 lines
2.5 KiB
Go
package structs
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/hashicorp/go-msgpack/codec"
|
|
)
|
|
|
|
var (
|
|
ErrNoLeader = fmt.Errorf("No cluster leader")
|
|
ErrNoRegionPath = fmt.Errorf("No path to region")
|
|
)
|
|
|
|
type MessageType uint8
|
|
|
|
const (
|
|
RegisterRequestType MessageType = iota
|
|
)
|
|
|
|
const (
|
|
// IgnoreUnknownTypeFlag is set along with a MessageType
|
|
// to indicate that the message type can be safely ignored
|
|
// if it is not recognized. This is for future proofing, so
|
|
// that new commands can be added in a way that won't cause
|
|
// old servers to crash when the FSM attempts to process them.
|
|
IgnoreUnknownTypeFlag MessageType = 128
|
|
)
|
|
|
|
// RPCInfo is used to describe common information about query
|
|
type RPCInfo interface {
|
|
RequestRegion() string
|
|
IsRead() bool
|
|
AllowStaleRead() bool
|
|
}
|
|
|
|
// QueryOptions is used to specify various flags for read queries
|
|
type QueryOptions struct {
|
|
// The target region for this query
|
|
Region string
|
|
|
|
// If set, any follower can service the request. Results
|
|
// may be arbitrarily stale.
|
|
AllowStale bool
|
|
}
|
|
|
|
func (q QueryOptions) RequestRegion() string {
|
|
return q.Region
|
|
}
|
|
|
|
// QueryOption only applies to reads, so always true
|
|
func (q QueryOptions) IsRead() bool {
|
|
return true
|
|
}
|
|
|
|
func (q QueryOptions) AllowStaleRead() bool {
|
|
return q.AllowStale
|
|
}
|
|
|
|
type WriteRequest struct {
|
|
Region string
|
|
}
|
|
|
|
func (w WriteRequest) RequestRegion() string {
|
|
// The target region for this request
|
|
return w.Region
|
|
}
|
|
|
|
// WriteRequest only applies to writes, always false
|
|
func (w WriteRequest) IsRead() bool {
|
|
return false
|
|
}
|
|
|
|
func (w WriteRequest) AllowStaleRead() bool {
|
|
return false
|
|
}
|
|
|
|
// QueryMeta allows a query response to include potentially
|
|
// useful metadata about a query
|
|
type QueryMeta struct {
|
|
// This is the index associated with the read
|
|
Index uint64
|
|
|
|
// If AllowStale is used, this is time elapsed since
|
|
// last contact between the follower and leader. This
|
|
// can be used to gauge staleness.
|
|
LastContact time.Duration
|
|
|
|
// Used to indicate if there is a known leader node
|
|
KnownLeader bool
|
|
}
|
|
|
|
// msgpackHandle is a shared handle for encoding/decoding of structs
|
|
var msgpackHandle = &codec.MsgpackHandle{}
|
|
|
|
// Decode is used to decode a MsgPack encoded object
|
|
func Decode(buf []byte, out interface{}) error {
|
|
return codec.NewDecoder(bytes.NewReader(buf), msgpackHandle).Decode(out)
|
|
}
|
|
|
|
// Encode is used to encode a MsgPack object with type prefix
|
|
func Encode(t MessageType, msg interface{}) ([]byte, error) {
|
|
var buf bytes.Buffer
|
|
buf.WriteByte(uint8(t))
|
|
err := codec.NewEncoder(&buf, msgpackHandle).Encode(msg)
|
|
return buf.Bytes(), err
|
|
}
|