github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/internal/grpcwrapper/rawtopic/rawtopicreader/rawtopicreader.go (about)

     1  package rawtopicreader
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"reflect"
     8  
     9  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Topic"
    10  
    11  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/grpcwrapper/rawtopic/rawtopiccommon"
    12  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/grpcwrapper/rawydb"
    13  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
    14  )
    15  
    16  var ErrUnexpectedMessageType = errors.New("unexpected message type")
    17  
    18  type GrpcStream interface {
    19  	Send(messageNew *Ydb_Topic.StreamReadMessage_FromClient) error
    20  	Recv() (*Ydb_Topic.StreamReadMessage_FromServer, error)
    21  	CloseSend() error
    22  }
    23  
    24  type StreamReader struct {
    25  	Stream GrpcStream
    26  }
    27  
    28  func (s StreamReader) CloseSend() error {
    29  	return s.Stream.CloseSend()
    30  }
    31  
    32  //nolint:funlen
    33  func (s StreamReader) Recv() (ServerMessage, error) {
    34  	grpcMess, err := s.Stream.Recv()
    35  	if xerrors.Is(err, io.EOF) {
    36  		return nil, err
    37  	}
    38  	if err != nil {
    39  		if !xerrors.IsErrorFromServer(err) {
    40  			err = xerrors.Transport(err)
    41  		}
    42  
    43  		return nil, err
    44  	}
    45  
    46  	var meta rawtopiccommon.ServerMessageMetadata
    47  	if err = meta.MetaFromStatusAndIssues(grpcMess); err != nil {
    48  		return nil, err
    49  	}
    50  	if !meta.Status.IsSuccess() {
    51  		return nil, xerrors.WithStackTrace(fmt.Errorf("ydb: bad status from topic server: %v", meta.Status))
    52  	}
    53  
    54  	switch m := grpcMess.GetServerMessage().(type) {
    55  	case *Ydb_Topic.StreamReadMessage_FromServer_InitResponse:
    56  		resp := &InitResponse{}
    57  		resp.ServerMessageMetadata = meta
    58  		resp.fromProto(m.InitResponse)
    59  
    60  		return resp, nil
    61  	case *Ydb_Topic.StreamReadMessage_FromServer_ReadResponse:
    62  		resp := &ReadResponse{}
    63  		resp.ServerMessageMetadata = meta
    64  		if err = resp.fromProto(m.ReadResponse); err != nil {
    65  			return nil, err
    66  		}
    67  
    68  		return resp, nil
    69  	case *Ydb_Topic.StreamReadMessage_FromServer_StartPartitionSessionRequest:
    70  		resp := &StartPartitionSessionRequest{}
    71  		resp.ServerMessageMetadata = meta
    72  		if err = resp.fromProto(m.StartPartitionSessionRequest); err != nil {
    73  			return nil, err
    74  		}
    75  
    76  		return resp, nil
    77  	case *Ydb_Topic.StreamReadMessage_FromServer_StopPartitionSessionRequest:
    78  		req := &StopPartitionSessionRequest{}
    79  		req.ServerMessageMetadata = meta
    80  		if err = req.fromProto(m.StopPartitionSessionRequest); err != nil {
    81  			return nil, err
    82  		}
    83  
    84  		return req, nil
    85  	case *Ydb_Topic.StreamReadMessage_FromServer_CommitOffsetResponse:
    86  		resp := &CommitOffsetResponse{}
    87  		resp.ServerMessageMetadata = meta
    88  		if err = resp.fromProto(m.CommitOffsetResponse); err != nil {
    89  			return nil, err
    90  		}
    91  
    92  		return resp, nil
    93  	case *Ydb_Topic.StreamReadMessage_FromServer_PartitionSessionStatusResponse:
    94  		resp := &PartitionSessionStatusResponse{}
    95  		resp.ServerMessageMetadata = meta
    96  		if err = resp.fromProto(m.PartitionSessionStatusResponse); err != nil {
    97  			return nil, err
    98  		}
    99  
   100  		return resp, nil
   101  	case *Ydb_Topic.StreamReadMessage_FromServer_UpdateTokenResponse:
   102  		resp := &UpdateTokenResponse{}
   103  		resp.ServerMessageMetadata = meta
   104  		resp.MustFromProto(m.UpdateTokenResponse)
   105  
   106  		return resp, nil
   107  	default:
   108  		return nil, xerrors.WithStackTrace(fmt.Errorf(
   109  			"ydb: receive unexpected message (%v): %w",
   110  			reflect.TypeOf(grpcMess.GetServerMessage()),
   111  			ErrUnexpectedMessageType,
   112  		))
   113  	}
   114  }
   115  
   116  func (s StreamReader) Send(msg ClientMessage) (err error) {
   117  	defer func() {
   118  		err = xerrors.Transport(err)
   119  	}()
   120  	switch m := msg.(type) {
   121  	case *InitRequest:
   122  		grpcMess := &Ydb_Topic.StreamReadMessage_FromClient{
   123  			ClientMessage: &Ydb_Topic.StreamReadMessage_FromClient_InitRequest{InitRequest: m.toProto()},
   124  		}
   125  
   126  		return s.Stream.Send(grpcMess)
   127  	case *ReadRequest:
   128  		grpcMess := &Ydb_Topic.StreamReadMessage_FromClient{
   129  			ClientMessage: &Ydb_Topic.StreamReadMessage_FromClient_ReadRequest{ReadRequest: m.toProto()},
   130  		}
   131  
   132  		return s.Stream.Send(grpcMess)
   133  	case *StartPartitionSessionResponse:
   134  		grpcMess := &Ydb_Topic.StreamReadMessage_FromClient{
   135  			ClientMessage: &Ydb_Topic.StreamReadMessage_FromClient_StartPartitionSessionResponse{
   136  				StartPartitionSessionResponse: m.toProto(),
   137  			},
   138  		}
   139  
   140  		return s.Stream.Send(grpcMess)
   141  	case *StopPartitionSessionResponse:
   142  		grpcMess := &Ydb_Topic.StreamReadMessage_FromClient{
   143  			ClientMessage: &Ydb_Topic.StreamReadMessage_FromClient_StopPartitionSessionResponse{
   144  				StopPartitionSessionResponse: m.toProto(),
   145  			},
   146  		}
   147  
   148  		return s.Stream.Send(grpcMess)
   149  	case *CommitOffsetRequest:
   150  		grpcMess := &Ydb_Topic.StreamReadMessage_FromClient{
   151  			ClientMessage: &Ydb_Topic.StreamReadMessage_FromClient_CommitOffsetRequest{
   152  				CommitOffsetRequest: m.toProto(),
   153  			},
   154  		}
   155  
   156  		return s.Stream.Send(grpcMess)
   157  	case *PartitionSessionStatusRequest:
   158  		grpcMess := &Ydb_Topic.StreamReadMessage_FromClient{
   159  			ClientMessage: &Ydb_Topic.StreamReadMessage_FromClient_PartitionSessionStatusRequest{
   160  				PartitionSessionStatusRequest: m.toProto(),
   161  			},
   162  		}
   163  
   164  		return s.Stream.Send(grpcMess)
   165  	case *UpdateTokenRequest:
   166  		grpcMess := &Ydb_Topic.StreamReadMessage_FromClient{
   167  			ClientMessage: &Ydb_Topic.StreamReadMessage_FromClient_UpdateTokenRequest{
   168  				UpdateTokenRequest: m.ToProto(),
   169  			},
   170  		}
   171  
   172  		return s.Stream.Send(grpcMess)
   173  	default:
   174  		return xerrors.WithStackTrace(fmt.Errorf("ydb: send unexpected message type: %v", reflect.TypeOf(msg)))
   175  	}
   176  }
   177  
   178  type ClientMessage interface {
   179  	isClientMessage()
   180  }
   181  
   182  type clientMessageImpl struct{}
   183  
   184  func (*clientMessageImpl) isClientMessage() {}
   185  
   186  type ServerMessage interface {
   187  	isServerMessage()
   188  	StatusData() rawtopiccommon.ServerMessageMetadata
   189  	SetStatus(status rawydb.StatusCode)
   190  }
   191  
   192  type serverMessageImpl struct{}
   193  
   194  func (*serverMessageImpl) isServerMessage() {}