Documentation ¶
Overview ¶
Package rpc provides RPC server and clients specific to Cockroach.
Package rpc is a generated protocol buffer package. It is generated from these files: cockroach/rpc/heartbeat.proto It has these top-level messages: RemoteOffset PingRequest PingResponse
Index ¶
- Constants
- Variables
- type Client
- func (c *Client) Call(serviceMethod string, args interface{}, reply interface{}) error
- func (c *Client) Close()
- func (c *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *rpc.Call) *rpc.Call
- func (c *Client) Healthy() <-chan struct{}
- func (c *Client) LocalAddr() net.Addr
- func (c *Client) RemoteAddr() net.Addr
- func (c *Client) WaitHealthy() bool
- type ClusterOffsetInterval
- type Context
- type HeartbeatService
- type MajorityIntervalNotFoundError
- type ManualHeartbeatService
- type PingRequest
- func (*PingRequest) GetUser() string
- func (m *PingRequest) Marshal() (data []byte, err error)
- func (m *PingRequest) MarshalTo(data []byte) (int, error)
- func (*PingRequest) ProtoMessage()
- func (m *PingRequest) Reset()
- func (m *PingRequest) Size() (n int)
- func (m *PingRequest) String() string
- func (m *PingRequest) Unmarshal(data []byte) error
- type PingResponse
- func (m *PingResponse) Marshal() (data []byte, err error)
- func (m *PingResponse) MarshalTo(data []byte) (int, error)
- func (*PingResponse) ProtoMessage()
- func (m *PingResponse) Reset()
- func (m *PingResponse) Size() (n int)
- func (m *PingResponse) String() string
- func (m *PingResponse) Unmarshal(data []byte) error
- type RemoteClockMonitor
- type RemoteOffset
- func (m *RemoteOffset) Marshal() (data []byte, err error)
- func (m *RemoteOffset) MarshalTo(data []byte) (int, error)
- func (*RemoteOffset) ProtoMessage()
- func (m *RemoteOffset) Reset()
- func (m *RemoteOffset) Size() (n int)
- func (r RemoteOffset) String() string
- func (m *RemoteOffset) Unmarshal(data []byte) error
- type Server
- func (s *Server) AddCloseCallback(cb func(conn net.Conn))
- func (s *Server) AddOpenCallback(cb func(conn net.Conn))
- func (s *Server) LocalCall(method string, args proto.Message, done chan *rpc.Call) bool
- func (s *Server) Register(name string, handler func(proto.Message) (proto.Message, error), ...) error
- func (s *Server) RegisterAsync(name string, public bool, ...) error
- func (s *Server) RegisterPublic(name string, handler func(proto.Message) (proto.Message, error), ...) error
- func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request)
Constants ¶
const DefaultRPCTimeout = 5 * time.Second
DefaultRPCTimeout is the default timeout on RPC calls.
Variables ¶
var ( ErrInvalidLengthHeartbeat = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowHeartbeat = fmt.Errorf("proto: integer overflow") )
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct { // `closer` is `close()`d when `Close` is called on the client. // It signals the end of the heartbeat run loop. When the run loop // exits, it `close()`es `Closed`, which signals to the outside // that the client has indeed stopped. Closed chan struct{} // contains filtered or unexported fields }
Client is a Cockroach-specific RPC client.
func NewClient ¶
NewClient returns a client RPC stub for the specified address (usually a TCP host:port, but for testing may be a unix domain socket). The process-wide client RPC cache is consulted first; if the requested client is not present, it's created and the cache is updated. Specify opts to fine tune client connection behavior or nil to use defaults (i.e. indefinite retries with exponential backoff).
The Closed channel is closed if the client's Close() method is invoked.
func (*Client) Close ¶
func (c *Client) Close()
Close closes the client, removing it from the clients cache and returning when the heartbeat goroutine has exited.
func (*Client) Go ¶
func (c *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *rpc.Call) *rpc.Call
Go delegates to net/rpc.Client.Go.
func (*Client) Healthy ¶
func (c *Client) Healthy() <-chan struct{}
Healthy returns a channel that is closed when the client becomes healthy. In the event of the client becoming unhealthy, future calls to Healthy() return a new channel.
func (*Client) RemoteAddr ¶
RemoteAddr returns remote address of the client.
func (*Client) WaitHealthy ¶
WaitHealthy returns the health of the Client. On the first connection of a newly-created Client, WaitHealthy will block for up to Context.HealthWait if its health has not yet been determined.
type ClusterOffsetInterval ¶
type ClusterOffsetInterval struct { Lowerbound int64 // The lowerbound on the offset in nanoseconds. Upperbound int64 // The upperbound on the offset in nanoseconds. }
ClusterOffsetInterval is the best interval we can construct to estimate this node's offset from the cluster.
func (ClusterOffsetInterval) String ¶
func (i ClusterOffsetInterval) String() string
type Context ¶
type Context struct { // Embed the base context. base.Context Stopper *stop.Stopper RemoteClocks *RemoteClockMonitor DisableCache bool // Disable client cache when calling NewClient() DisableReconnects bool // Disable client reconnects HealthWait time.Duration HeartbeatInterval time.Duration HeartbeatTimeout time.Duration LocalServer *Server // Holds the local RPC server handle LocalAddr string // contains filtered or unexported fields }
Context contains the fields required by the rpc framework.
func NewContext ¶
NewContext creates an rpc Context with the supplied values.
func (*Context) Copy ¶
Copy creates a copy of the rpc Context config values, but with a new remote clock monitor.
func (*Context) SetLocalServer ¶
SetLocalServer sets the local RPC server handle to the context.
type HeartbeatService ¶
type HeartbeatService struct {
// contains filtered or unexported fields
}
A HeartbeatService exposes a method to echo its request params. It doubles as a way to measure the offset of the server from other nodes. It uses the clock to return the server time every heartbeat. It also keeps track of remote clocks sent to it by storing them in the remoteClockMonitor.
func (*HeartbeatService) Ping ¶
Ping echos the contents of the request to the response, and returns the server's current clock value, allowing the requester to measure its clock. The requester should also estimate its offset from this server along with the requester's address.
func (*HeartbeatService) Register ¶
func (hs *HeartbeatService) Register(server *Server) error
Register this service on the given RPC server.
type MajorityIntervalNotFoundError ¶
type MajorityIntervalNotFoundError struct{}
MajorityIntervalNotFoundError indicates that we could not find a majority overlap in our estimate of remote clocks.
func (MajorityIntervalNotFoundError) Error ¶
func (MajorityIntervalNotFoundError) Error() string
type ManualHeartbeatService ¶
type ManualHeartbeatService struct {
// contains filtered or unexported fields
}
A ManualHeartbeatService allows manual control of when heartbeats occur, to facilitate testing.
func (*ManualHeartbeatService) Ping ¶
Ping waits until the heartbeat service is ready to respond to a Heartbeat.
func (*ManualHeartbeatService) Register ¶
func (mhs *ManualHeartbeatService) Register(server *Server) error
Register this service on the given RPC server.
type PingRequest ¶
type PingRequest struct { // Echo this string with PingResponse. Ping string `protobuf:"bytes,1,opt,name=ping" json:"ping"` // The last offset the client measured with the server. Offset RemoteOffset `protobuf:"bytes,2,opt,name=offset" json:"offset"` // The address of the client. Addr string `protobuf:"bytes,3,opt,name=addr" json:"addr"` }
A PingRequest specifies the string to echo in response. Fields are exported so that they will be serialized in the rpc call.
func (*PingRequest) GetUser ¶
func (*PingRequest) GetUser() string
GetUser implements security.RequestWithUser. Heartbeat messages are always sent by the node user.
func (*PingRequest) Marshal ¶
func (m *PingRequest) Marshal() (data []byte, err error)
func (*PingRequest) ProtoMessage ¶
func (*PingRequest) ProtoMessage()
func (*PingRequest) Reset ¶
func (m *PingRequest) Reset()
func (*PingRequest) Size ¶
func (m *PingRequest) Size() (n int)
func (*PingRequest) String ¶
func (m *PingRequest) String() string
func (*PingRequest) Unmarshal ¶
func (m *PingRequest) Unmarshal(data []byte) error
type PingResponse ¶
type PingResponse struct { // An echo of value sent with PingRequest. Pong string `protobuf:"bytes,1,opt,name=pong" json:"pong"` ServerTime int64 `protobuf:"varint,2,opt,name=server_time" json:"server_time"` }
A PingResponse contains the echoed ping request string.
func (*PingResponse) Marshal ¶
func (m *PingResponse) Marshal() (data []byte, err error)
func (*PingResponse) ProtoMessage ¶
func (*PingResponse) ProtoMessage()
func (*PingResponse) Reset ¶
func (m *PingResponse) Reset()
func (*PingResponse) Size ¶
func (m *PingResponse) Size() (n int)
func (*PingResponse) String ¶
func (m *PingResponse) String() string
func (*PingResponse) Unmarshal ¶
func (m *PingResponse) Unmarshal(data []byte) error
type RemoteClockMonitor ¶
type RemoteClockMonitor struct {
// contains filtered or unexported fields
}
RemoteClockMonitor keeps track of the most recent measurements of remote offsets from this node to connected nodes.
func (*RemoteClockMonitor) MonitorRemoteOffsets ¶
func (r *RemoteClockMonitor) MonitorRemoteOffsets(stopper *stop.Stopper)
MonitorRemoteOffsets periodically checks that the offset of this server's clock from the true cluster time is within MaxOffset. If the offset exceeds MaxOffset, then this method will trigger a fatal error, causing the node to suicide.
func (*RemoteClockMonitor) UpdateOffset ¶
func (r *RemoteClockMonitor) UpdateOffset(addr string, offset RemoteOffset)
UpdateOffset is a thread-safe way to update the remote clock measurements.
It only updates the offset for addr if one the following three cases holds: 1. There is no prior offset for that address. 2. The old offset for addr was measured before r.lastMonitoredAt. We never use values during monitoring that are older than r.lastMonitoredAt. 3. The new offset's error is smaller than the old offset's error.
The third case allows the monitor to use the most precise clock reading of the remote addr during the next findOffsetInterval() invocation. We may measure the remote clock several times before we next calculate the cluster offset. When we do the measurement, we want to use the reading with the smallest error. Because monitorInterval > heartbeatInterval, this gives us several chances to accurately read the remote clock. Note that we don't want monitorInterval to be too large, else we might end up relying on old information.
type RemoteOffset ¶
type RemoteOffset struct { // The estimated offset from the remote server, in nanoseconds. Offset int64 `protobuf:"varint,1,opt,name=offset" json:"offset"` // The maximum error of the measured offset, in nanoseconds. Uncertainty int64 `protobuf:"varint,2,opt,name=uncertainty" json:"uncertainty"` // Measurement time, in nanoseconds from unix epoch. MeasuredAt int64 `protobuf:"varint,3,opt,name=measured_at" json:"measured_at"` }
RemoteOffset keeps track of this client's estimate of its offset from a remote server. Uncertainty is the maximum error in the reading of this offset, so that the real offset should be in the interval [Offset - Uncertainty, Offset + Uncertainty]. If the last heartbeat timed out, Offset = 0.
Offset and Uncertainty are measured using the remote clock reading technique described in http://se.inf.tu-dresden.de/pubs/papers/SRDS1994.pdf, page 6.
func (*RemoteOffset) Marshal ¶
func (m *RemoteOffset) Marshal() (data []byte, err error)
func (*RemoteOffset) ProtoMessage ¶
func (*RemoteOffset) ProtoMessage()
func (*RemoteOffset) Reset ¶
func (m *RemoteOffset) Reset()
func (*RemoteOffset) Size ¶
func (m *RemoteOffset) Size() (n int)
func (RemoteOffset) String ¶
func (r RemoteOffset) String() string
String formats the RemoteOffset for human readability.
func (*RemoteOffset) Unmarshal ¶
func (m *RemoteOffset) Unmarshal(data []byte) error
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is a Cockroach-specific RPC server. By default it handles a simple heartbeat protocol to measure link health. It also supports close callbacks.
TODO(spencer): heartbeat protocol should also measure link latency.
func (*Server) AddCloseCallback ¶
AddCloseCallback adds a callback to the closeCallbacks slice to be invoked when a connection is closed.
func (*Server) AddOpenCallback ¶
AddOpenCallback adds a callback to the openCallbacks slice to be invoked when a connection is opened.
func (*Server) LocalCall ¶
LocalCall invokes the specified method directly. Returns false if the method is public and cannot be served with a local call. Local calls skip the standard authorization checks, hence the restriction against calling public methods which are accessible from end users.
func (*Server) Register ¶
func (s *Server) Register(name string, handler func(proto.Message) (proto.Message, error), reqPrototype proto.Message) error
Register a new method handler. `name` is a qualified name of the form "Service.Name". `handler` is a function that takes an argument of the same type as `reqPrototype`. Both the argument and return value of 'handler' should be a pointer to a protocol message type. The handler function will be executed in a new goroutine. Only the "node" system user is allowed to use these endpoints.
func (*Server) RegisterAsync ¶
func (s *Server) RegisterAsync(name string, public bool, handler func(proto.Message, func(proto.Message, error)), reqPrototype proto.Message) error
RegisterAsync registers an asynchronous method handler. Instead of returning a (proto.Message, error) tuple, an asynchronous handler receives a callback which it must execute when it is complete. Note that async handlers are started in the RPC server's goroutine and must not block (i.e. they must start a goroutine or write to a channel promptly). However, the fact that they are started in the RPC server's goroutine guarantees that the order of requests as they were read from the connection is preserved. If 'public' is true, all users may call this method, otherwise "node" users only.