Skip to content

Commit

Permalink
deprecate stream, move documentation to client|server stream (#2198)
Browse files Browse the repository at this point in the history
docs: deprecate stream, move documentation to client|server stream

Deprecate Stream, and move the methods and documention to ServerStream
and ClientStream. This is due to the fact that there are different
semantics for SendMsg, and it's quite confusing to document one method
for two things. Furthermore, Stream is not actually used in any way
other than to be inherited by ClientStream and ServerStream.

Relevant issue: #2159
  • Loading branch information
jeanbza authored Jul 9, 2018
1 parent 264daa2 commit 50de898
Showing 1 changed file with 69 additions and 41 deletions.
110 changes: 69 additions & 41 deletions stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,43 +59,20 @@ type StreamDesc struct {

// Stream defines the common interface a client or server stream has to satisfy.
//
// All errors returned from Stream are compatible with the status package.
// Deprecated: See ClientStream and ServerStream documentation instead.
type Stream interface {
// Context returns the context for this stream. If called from the client,
// Should be done after Header or RecvMsg. Otherwise, retries may not be
// possible to perform.
// Deprecated: See ClientStream and ServerStream documentation instead.
Context() context.Context
// SendMsg is generally called by generated code. On error, SendMsg aborts
// the stream and returns an RPC status on the client side. On the server
// side, it simply returns the error to the caller.
//
// SendMsg blocks until:
// - It schedules m with the transport, or
// - The stream is done, or
// - The stream breaks.
//
// SendMsg does not wait for an ack. An untimely stream closure
// can result in any buffered messages along the way (including
// those in the client-side buffer that comes with gRPC by default)
// being lost. To ensure delivery, users must call RecvMsg until
// receiving an EOF before closing the stream.
//
// It's safe to have a goroutine calling SendMsg and another
// goroutine calling RecvMsg on the same stream at the same
// time. It is not safe to call SendMsg on the same stream
// in different goroutines.
// Deprecated: See ClientStream and ServerStream documentation instead.
SendMsg(m interface{}) error
// RecvMsg blocks until it receives a message or the stream is
// done. On client side, it returns io.EOF when the stream is done. On
// any other error, it aborts the stream and returns an RPC status. On
// server side, it simply returns the error to the caller.
// It's safe to have a goroutine calling SendMsg and another goroutine calling
// recvMsg on the same stream at the same time.
// But it is not safe to call RecvMsg on the same stream in different goroutines.
// Deprecated: See ClientStream and ServerStream documentation instead.
RecvMsg(m interface{}) error
}

// ClientStream defines the interface a client stream has to satisfy.
// ClientStream defines the client-side behavior of a streaming RPC.
//
// All errors returned from ClientStream methods are compatible with the
// status package.
type ClientStream interface {
// Header returns the header metadata received from the server if there
// is any. It blocks if the metadata is not ready to read.
Expand All @@ -107,13 +84,38 @@ type ClientStream interface {
// CloseSend closes the send direction of the stream. It closes the stream
// when non-nil error is met.
CloseSend() error
// Stream.SendMsg() may return a non-nil error when something wrong happens sending
// the request. The returned error indicates the status of this sending, not the final
// status of the RPC.
// Context returns the context for this stream.
//
// It should not be called until after Header or RecvMsg has returned. Once
// called, subsequent client-side retries are disabled.
Context() context.Context
// SendMsg is generally called by generated code. On error, SendMsg aborts
// the stream. If the error was generated by the client, the status is
// returned directly; otherwise, io.EOF is returned and the status of
// the stream may be discovered using RecvMsg.
//
// SendMsg blocks until:
// - There is sufficient flow control to schedule m with the transport, or
// - The stream is done, or
// - The stream breaks.
//
// SendMsg does not wait until the message is received by the server. An
// untimely stream closure may result in lost messages. To ensure delivery,
// users should ensure the RPC completed successfully using RecvMsg.
//
// Always call Stream.RecvMsg() to drain the stream and get the final
// status, otherwise there could be leaked resources.
Stream
// It is safe to have a goroutine calling SendMsg and another goroutine
// calling RecvMsg on the same stream at the same time, but it is not safe
// to call SendMsg on the same stream in different goroutines.
SendMsg(m interface{}) error
// RecvMsg blocks until it receives a message into m or the stream is
// done. It returns io.EOF when the stream completes successfully. On
// any other error, the stream is aborted and the error contains the RPC
// status.
//
// It is safe to have a goroutine calling SendMsg and another goroutine
// calling RecvMsg on the same stream at the same time, but it is not
// safe to call RecvMsg on the same stream in different goroutines.
RecvMsg(m interface{}) error
}

// NewStream creates a new Stream for the client side. This is typically
Expand Down Expand Up @@ -144,8 +146,6 @@ func (cc *ClientConn) NewStream(ctx context.Context, desc *StreamDesc, method st
}

// NewClientStream is a wrapper for ClientConn.NewStream.
//
// DEPRECATED: Use ClientConn.NewStream instead.
func NewClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) {
return cc.NewStream(ctx, desc, method, opts...)
}
Expand Down Expand Up @@ -845,7 +845,10 @@ func (a *csAttempt) finish(err error) {
a.mu.Unlock()
}

// ServerStream defines the interface a server stream has to satisfy.
// ServerStream defines the server-side behavior of a streaming RPC.
//
// All errors returned from ServerStream methods are compatible with the
// status package.
type ServerStream interface {
// SetHeader sets the header metadata. It may be called multiple times.
// When call multiple times, all the provided metadata will be merged.
Expand All @@ -861,7 +864,32 @@ type ServerStream interface {
// SetTrailer sets the trailer metadata which will be sent with the RPC status.
// When called more than once, all the provided metadata will be merged.
SetTrailer(metadata.MD)
Stream
// Context returns the context for this stream.
Context() context.Context
// SendMsg sends a message. On error, SendMsg aborts the stream and the
// error is returned directly.
//
// SendMsg blocks until:
// - There is sufficient flow control to schedule m with the transport, or
// - The stream is done, or
// - The stream breaks.
//
// SendMsg does not wait until the message is received by the client. An
// untimely stream closure may result in lost messages.
//
// It is safe to have a goroutine calling SendMsg and another goroutine
// calling RecvMsg on the same stream at the same time, but it is not safe
// to call SendMsg on the same stream in different goroutines.
SendMsg(m interface{}) error
// RecvMsg blocks until it receives a message into m or the stream is
// done. It returns io.EOF when the client has performed a CloseSend. On
// any non-EOF error, the stream is aborted and the error contains the
// RPC status.
//
// It is safe to have a goroutine calling SendMsg and another goroutine
// calling RecvMsg on the same stream at the same time, but it is not
// safe to call RecvMsg on the same stream in different goroutines.
RecvMsg(m interface{}) error
}

// serverStream implements a server side Stream.
Expand Down

0 comments on commit 50de898

Please sign in to comment.