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