rpc

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 6, 2019 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package rpc implements zrepl daemon-to-daemon RPC protocol on top of a transport provided by package transport. The zrepl documentation refers to the client as the `active side` and to the server as the `passive side`.

Design Considerations

zrepl has non-standard requirements to remote procedure calls (RPC): whereas the coordination of replication (the planning phase) mostly consists of regular unary calls, the actual data transfer requires a high-throughput, low-overhead solution.

Specifically, the requirements for data transfer is to perform a copy of an io.Reader over the wire, such that an io.EOF of the original reader corresponds to an io.EOF on the receiving side. If any other error occurs while reading from the original io.Reader on the sender, the receiver should receive the contents of that error in some form (usually as a trailer message) A common implementation technique for above data transfer is chunking, for example in HTTP: https://tools.ietf.org/html/rfc2616#section-3.6.1

With regards to regular RPCs, gRPC is a popular implementation based on protocol buffers and thus code generation. gRPC also supports bi-directional streaming RPC, and it is possible to implement chunked transfer through the use of streams.

For zrepl however, both HTTP and manually implemented chunked transfer using gRPC were found to have significant CPU overhead at transfer speeds to be expected even with hobbyist users.

However, it is nice to piggyback on the code generation provided by protobuf / gRPC, in particular since the majority of call types are regular unary RPCs for which the higher overhead of gRPC is acceptable.

Hence, this package attempts to combine the best of both worlds:

GRPC for Coordination and Dataconn for Bulk Data Transfer

This package's Client uses its transport.Connecter to maintain separate control and data connections to the Server. The control connection is used by an instance of pdu.ReplicationClient whose 'regular' unary RPC calls are re-exported. The data connection is used by an instance of dataconn.Client and is used for bulk data transfer, namely `Send` and `Receive`.

The following ASCII diagram gives an overview of how the individual building blocks are glued together:

                 +------------+
                 | rpc.Client |
                 +------------+
                   |         |
          +--------+         +------------+
          |                               |
+---------v-----------+          +--------v------+
|pdu.ReplicationClient|          |dataconn.Client|
+---------------------+          +--------v------+
          | label:            label:      |
          | zrepl_control      zrepl_data |
          +--------+         +------------+
                   |         |
                +--v---------v---+
                |  transportmux  |
                +-------+--------+
                        | uses
                +-------v--------+
                |versionhandshake|
                +-------+--------+
                        | uses
                 +------v------+
                 |  transport  |
                 +------+------+
                        |
                     NETWORK
                        |
                 +------+------+
                 |  transport  |
                 +------^------+
                        | uses
                +-------+--------+
                |versionhandshake|
                +-------^--------+
                        | uses
                +-------+--------+
                |  transportmux  |
                +--^--------^----+
                   |        |
          +--------+        --------------+       ---
          |                               |        |
          | label:            label:      |        |
          | zrepl_control      zrepl_data |        |
    +-----+----+              +-----------+---+    |
    |netadaptor|              |dataconn.Server|    | rpc.Server
    |     +    |              +------+--------+    |
    |grpcclient|                     |             |
    |identity  |                     |             |
    +-----+----+                     |             |
          |                          |             |
+---------v-----------+              |             |
|pdu.ReplicationServer|              |             |
+---------+-----------+              |             |
          |                          |            ---
          +----------+  +------------+
                     |  |
                 +---v--v-----+
                 |  Handler   |
                 +------------+
        (usually endpoint.{Sender,Receiver})

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func WithLoggers

func WithLoggers(ctx context.Context, loggers Loggers) context.Context

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client implements the active side of a replication setup. It satisfies the Endpoint, Sender and Receiver interface defined by package replication.

func NewClient

func NewClient(cn transport.Connecter, loggers Loggers) *Client

config must be validated, NewClient will panic if it is not valid

func (*Client) Close

func (c *Client) Close()

func (*Client) DestroySnapshots

func (c *Client) DestroySnapshots(ctx context.Context, in *pdu.DestroySnapshotsReq) (*pdu.DestroySnapshotsRes, error)

func (*Client) ListFilesystemVersions

func (c *Client) ListFilesystemVersions(ctx context.Context, in *pdu.ListFilesystemVersionsReq) (*pdu.ListFilesystemVersionsRes, error)

func (*Client) ListFilesystems

func (c *Client) ListFilesystems(ctx context.Context, in *pdu.ListFilesystemReq) (*pdu.ListFilesystemRes, error)

func (*Client) Receive

func (c *Client) Receive(ctx context.Context, req *pdu.ReceiveReq, streamCopier zfs.StreamCopier) (*pdu.ReceiveRes, error)

func (*Client) ReplicationCursor

func (c *Client) ReplicationCursor(ctx context.Context, in *pdu.ReplicationCursorReq) (*pdu.ReplicationCursorRes, error)

func (*Client) ResetConnectBackoff

func (c *Client) ResetConnectBackoff()

func (*Client) Send

func (c *Client) Send(ctx context.Context, r *pdu.SendReq) (*pdu.SendRes, zfs.StreamCopier, error)

callers must ensure that the returned io.ReadCloser is closed TODO expose dataClient interface to the outside world

func (*Client) WaitForConnectivity

func (c *Client) WaitForConnectivity(ctx context.Context) error

type DialContextFunc

type DialContextFunc = func(ctx context.Context, network string, addr string) (net.Conn, error)

type Handler

type Handler interface {
	pdu.ReplicationServer
	dataconn.Handler
}

type HandlerContextInterceptor

type HandlerContextInterceptor func(ctx context.Context) context.Context

type Logger

type Logger = logger.Logger

type Loggers

type Loggers struct {
	General Logger
	Control Logger
	Data    Logger
}

/ All fields must be non-nil

func GetLoggersOrPanic

func GetLoggersOrPanic(ctx context.Context) Loggers

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server abstracts the accept and request routing infrastructure for the passive side of a replication setup.

func NewServer

func NewServer(handler Handler, loggers Loggers, ctxInterceptor HandlerContextInterceptor) *Server

config must be valid (use its Validate function).

func (*Server) Serve

The context is used for cancellation only. Serve never returns an error, it logs them to the Server's logger.

Directories

Path Synopsis
heartbeatconn/integration_test_variablereceiverate
This integration test exercises the behavior of heartbeatconn where the server is slow at handling the data received over the connection.
This integration test exercises the behavior of heartbeatconn where the server is slow at handling the data received over the connection.
microbenchmark
microbenchmark to manually test rpc/dataconn perforamnce With stdin / stdout on client and server, simulating zfs send|recv piping ./microbenchmark -appmode server | pv -r > /dev/null ./microbenchmark -appmode client -direction recv < /dev/zero Without the overhead of pipes (just protocol perforamnce, mostly useful with perf bc no bw measurement) ./microbenchmark -appmode client -direction recv -devnoopWriter -devnoopReader ./microbenchmark -appmode server -devnoopReader -devnoopWriter
microbenchmark to manually test rpc/dataconn perforamnce With stdin / stdout on client and server, simulating zfs send|recv piping ./microbenchmark -appmode server | pv -r > /dev/null ./microbenchmark -appmode client -direction recv < /dev/zero Without the overhead of pipes (just protocol perforamnce, mostly useful with perf bc no bw measurement) ./microbenchmark -appmode client -direction recv -devnoopWriter -devnoopReader ./microbenchmark -appmode server -devnoopReader -devnoopWriter
timeoutconn
package timeoutconn wraps a Wire to provide idle timeouts based on Set{Read,Write}Deadline.
package timeoutconn wraps a Wire to provide idle timeouts based on Set{Read,Write}Deadline.
timeoutconn/internal/wireevaluator
a tool to test whether a given transport implements the timeoutconn.Wire interface
a tool to test whether a given transport implements the timeoutconn.Wire interface
Package grpcclientidentity makes the client identity provided by github.com/zrepl/zrepl/daemon/transport/serve.{AuthenticatedListener,AuthConn} available to gRPC service handlers.
Package grpcclientidentity makes the client identity provided by github.com/zrepl/zrepl/daemon/transport/serve.{AuthenticatedListener,AuthConn} available to gRPC service handlers.
example
This package demonstrates how the grpcclientidentity package can be used to set up a gRPC greeter service.
This package demonstrates how the grpcclientidentity package can be used to set up a gRPC greeter service.
grpchelper
Package grpchelper wraps the adaptors implemented by package grpcclientidentity into a less flexible API which, however, ensures that the individual adaptor primitive's expectations are met and hence do not panic.
Package grpchelper wraps the adaptors implemented by package grpcclientidentity into a less flexible API which, however, ensures that the individual adaptor primitive's expectations are met and hence do not panic.
Package netadaptor implements an adaptor from transport.AuthenticatedListener to net.Listener.
Package netadaptor implements an adaptor from transport.AuthenticatedListener to net.Listener.
Package transportmux wraps a transport.{Connecter,AuthenticatedListener} to distinguish different connection types based on a label sent from client to server on connection establishment.
Package transportmux wraps a transport.{Connecter,AuthenticatedListener} to distinguish different connection types based on a label sent from client to server on connection establishment.
Package versionhandshake wraps a transport.{Connecter,AuthenticatedListener} to add an exchange of protocol version information on connection establishment.
Package versionhandshake wraps a transport.{Connecter,AuthenticatedListener} to add an exchange of protocol version information on connection establishment.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL