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