1// Copyright (C) 2019 Storj Labs, Inc. 2// See LICENSE for copying information. 3 4package drpc 5 6import ( 7 "context" 8 "io" 9 10 "github.com/zeebo/errs" 11) 12 13// These error classes represent some common errors that drpc generates. 14var ( 15 Error = errs.Class("drpc") 16 InternalError = errs.Class("internal error") 17 ProtocolError = errs.Class("protocol error") 18 ClosedError = errs.Class("closed") 19) 20 21// Transport is an interface describing what is required for a drpc connection. 22type Transport interface { 23 io.Reader 24 io.Writer 25 io.Closer 26} 27 28// Message is a protobuf message. It is expected to be used with an Encoding. 29// This exists so that one can use whatever protobuf library/runtime they want. 30type Message interface{} 31 32// Conn represents a client connection to a server. 33type Conn interface { 34 // Close closes the connection. 35 Close() error 36 37 // Closed returns a channel that is closed if the connection is definitely closed. 38 Closed() <-chan struct{} 39 40 // Invoke issues a unary RPC to the remote. Only one Invoke or Stream may be 41 // open at once. 42 Invoke(ctx context.Context, rpc string, enc Encoding, in, out Message) error 43 44 // NewStream starts a stream with the remote. Only one Invoke or Stream may be 45 // open at once. 46 NewStream(ctx context.Context, rpc string, enc Encoding) (Stream, error) 47} 48 49// Stream is a bi-directional stream of messages to some other party. 50type Stream interface { 51 // Context returns the context associated with the stream. It is canceled 52 // when the Stream is closed and no more messages will ever be sent or 53 // received on it. 54 Context() context.Context 55 56 // MsgSend sends the Message to the remote. 57 MsgSend(msg Message, enc Encoding) error 58 59 // MsgRecv receives a Message from the remote. 60 MsgRecv(msg Message, enc Encoding) error 61 62 // CloseSend signals to the remote that we will no longer send any messages. 63 CloseSend() error 64 65 // Close closes the stream. 66 Close() error 67} 68 69// Receiver is invoked by a server for a given RPC. 70type Receiver = func(srv interface{}, ctx context.Context, in1, in2 interface{}) (out Message, err error) 71 72// Description is the interface implemented by things that can be registered by 73// a Server. 74type Description interface { 75 // NumMethods returns the number of methods available. 76 NumMethods() int 77 78 // Method returns the information about the nth method along with a handler 79 // to invoke it. The method interface that it returns is expected to be 80 // a method expression like `(*Type).HandlerName`. 81 Method(n int) (rpc string, encoding Encoding, receiver Receiver, method interface{}, ok bool) 82} 83 84// Mux is a type that can have an implementation and a Description registered with it. 85type Mux interface { 86 // Register marks that the description should dispatch RPCs that it describes to 87 // the provided srv. 88 Register(srv interface{}, desc Description) error 89} 90 91// Handler handles streams and RPCs dispatched to it by a Server. 92type Handler interface { 93 // HandleRPC executes the RPC identified by the rpc string using the stream to 94 // communicate with the remote. 95 HandleRPC(stream Stream, rpc string) (err error) 96} 97 98// Encoding represents a way to marshal/unmarshal Message types. 99type Encoding interface { 100 // Marshal returns the encoded form of msg. 101 Marshal(msg Message) ([]byte, error) 102 103 // Unmarshal reads the encoded form of some Message into msg. 104 // The buf is expected to contain only a single complete Message. 105 Unmarshal(buf []byte, msg Message) error 106} 107