github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/topic/topicclientinternal/client.go (about)

     1  package topicclientinternal
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/ydb-platform/ydb-go-genproto/Ydb_Topic_V1"
     7  	"google.golang.org/grpc"
     8  
     9  	"github.com/ydb-platform/ydb-go-sdk/v3/credentials"
    10  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/grpcwrapper/rawtopic"
    11  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/grpcwrapper/rawydb"
    12  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/topic"
    13  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/topic/topicreaderinternal"
    14  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/topic/topicwriterinternal"
    15  	"github.com/ydb-platform/ydb-go-sdk/v3/retry"
    16  	"github.com/ydb-platform/ydb-go-sdk/v3/topic/topicoptions"
    17  	"github.com/ydb-platform/ydb-go-sdk/v3/topic/topicreader"
    18  	"github.com/ydb-platform/ydb-go-sdk/v3/topic/topictypes"
    19  	"github.com/ydb-platform/ydb-go-sdk/v3/topic/topicwriter"
    20  	"github.com/ydb-platform/ydb-go-sdk/v3/trace"
    21  )
    22  
    23  type Client struct {
    24  	cfg                    topic.Config
    25  	cred                   credentials.Credentials
    26  	defaultOperationParams rawydb.OperationParams
    27  	rawClient              rawtopic.Client
    28  }
    29  
    30  func New(
    31  	ctx context.Context,
    32  	conn grpc.ClientConnInterface,
    33  	cred credentials.Credentials,
    34  	opts ...topicoptions.TopicOption,
    35  ) (*Client, error) {
    36  	rawClient := rawtopic.NewClient(Ydb_Topic_V1.NewTopicServiceClient(conn))
    37  
    38  	cfg := newTopicConfig(opts...)
    39  
    40  	var defaultOperationParams rawydb.OperationParams
    41  	topic.OperationParamsFromConfig(&defaultOperationParams, &cfg.Common)
    42  
    43  	return &Client{
    44  		cfg:                    cfg,
    45  		cred:                   cred,
    46  		defaultOperationParams: defaultOperationParams,
    47  		rawClient:              rawClient,
    48  	}, nil
    49  }
    50  
    51  func newTopicConfig(opts ...topicoptions.TopicOption) topic.Config {
    52  	c := topic.Config{
    53  		Trace: &trace.Topic{},
    54  	}
    55  	for _, o := range opts {
    56  		if o != nil {
    57  			o(&c)
    58  		}
    59  	}
    60  
    61  	return c
    62  }
    63  
    64  // Close the client
    65  func (c *Client) Close(_ context.Context) error {
    66  	return nil
    67  }
    68  
    69  // Alter topic options
    70  func (c *Client) Alter(ctx context.Context, path string, opts ...topicoptions.AlterOption) error {
    71  	req := &rawtopic.AlterTopicRequest{}
    72  	req.OperationParams = c.defaultOperationParams
    73  	req.Path = path
    74  	for _, o := range opts {
    75  		if o != nil {
    76  			o.ApplyAlterOption(req)
    77  		}
    78  	}
    79  
    80  	call := func(ctx context.Context) error {
    81  		_, alterErr := c.rawClient.AlterTopic(ctx, req)
    82  
    83  		return alterErr
    84  	}
    85  
    86  	if c.cfg.AutoRetry() {
    87  		return retry.Retry(ctx, call,
    88  			retry.WithIdempotent(true),
    89  			retry.WithTrace(c.cfg.TraceRetry()),
    90  		)
    91  	}
    92  
    93  	return call(ctx)
    94  }
    95  
    96  // Create new topic
    97  func (c *Client) Create(
    98  	ctx context.Context,
    99  	path string,
   100  	opts ...topicoptions.CreateOption,
   101  ) error {
   102  	req := &rawtopic.CreateTopicRequest{}
   103  	req.OperationParams = c.defaultOperationParams
   104  	req.Path = path
   105  
   106  	for _, o := range opts {
   107  		if o != nil {
   108  			o.ApplyCreateOption(req)
   109  		}
   110  	}
   111  
   112  	call := func(ctx context.Context) error {
   113  		_, createErr := c.rawClient.CreateTopic(ctx, req)
   114  
   115  		return createErr
   116  	}
   117  
   118  	if c.cfg.AutoRetry() {
   119  		return retry.Retry(ctx, call,
   120  			retry.WithIdempotent(true),
   121  			retry.WithTrace(c.cfg.TraceRetry()),
   122  		)
   123  	}
   124  
   125  	return call(ctx)
   126  }
   127  
   128  // Describe topic
   129  func (c *Client) Describe(
   130  	ctx context.Context,
   131  	path string,
   132  	opts ...topicoptions.DescribeOption,
   133  ) (res topictypes.TopicDescription, _ error) {
   134  	req := rawtopic.DescribeTopicRequest{
   135  		OperationParams: c.defaultOperationParams,
   136  		Path:            path,
   137  	}
   138  
   139  	for _, o := range opts {
   140  		if o != nil {
   141  			o(&req)
   142  		}
   143  	}
   144  
   145  	var rawRes rawtopic.DescribeTopicResult
   146  
   147  	call := func(ctx context.Context) (describeErr error) {
   148  		rawRes, describeErr = c.rawClient.DescribeTopic(ctx, req)
   149  
   150  		return describeErr
   151  	}
   152  
   153  	var err error
   154  
   155  	if c.cfg.AutoRetry() {
   156  		err = retry.Retry(ctx, call,
   157  			retry.WithIdempotent(true),
   158  			retry.WithTrace(c.cfg.TraceRetry()),
   159  		)
   160  	} else {
   161  		err = call(ctx)
   162  	}
   163  
   164  	if err != nil {
   165  		return res, err
   166  	}
   167  
   168  	res.FromRaw(&rawRes)
   169  
   170  	return res, nil
   171  }
   172  
   173  // Drop topic
   174  func (c *Client) Drop(ctx context.Context, path string, opts ...topicoptions.DropOption) error {
   175  	req := rawtopic.DropTopicRequest{}
   176  	req.OperationParams = c.defaultOperationParams
   177  	req.Path = path
   178  
   179  	for _, o := range opts {
   180  		if o != nil {
   181  			o.ApplyDropOption(&req)
   182  		}
   183  	}
   184  
   185  	call := func(ctx context.Context) error {
   186  		_, removeErr := c.rawClient.DropTopic(ctx, req)
   187  
   188  		return removeErr
   189  	}
   190  
   191  	if c.cfg.AutoRetry() {
   192  		return retry.Retry(ctx, call,
   193  			retry.WithIdempotent(true),
   194  			retry.WithTrace(c.cfg.TraceRetry()),
   195  		)
   196  	}
   197  
   198  	return call(ctx)
   199  }
   200  
   201  // StartReader create new topic reader and start pull messages from server
   202  // it is fast non block call, connection will start in background
   203  func (c *Client) StartReader(
   204  	consumer string,
   205  	readSelectors topicoptions.ReadSelectors,
   206  	opts ...topicoptions.ReaderOption,
   207  ) (*topicreader.Reader, error) {
   208  	var connector topicreaderinternal.TopicSteamReaderConnect = func(ctx context.Context) (
   209  		topicreaderinternal.RawTopicReaderStream, error,
   210  	) {
   211  		return c.rawClient.StreamRead(ctx)
   212  	}
   213  
   214  	defaultOpts := []topicoptions.ReaderOption{
   215  		topicoptions.WithCommonConfig(c.cfg.Common),
   216  		topicreaderinternal.WithCredentials(c.cred),
   217  		topicreaderinternal.WithTrace(c.cfg.Trace),
   218  		topicoptions.WithReaderStartTimeout(topic.DefaultStartTimeout),
   219  	}
   220  	opts = append(defaultOpts, opts...)
   221  
   222  	internalReader := topicreaderinternal.NewReader(connector, consumer, readSelectors, opts...)
   223  	trace.TopicOnReaderStart(internalReader.Tracer(), internalReader.ID(), consumer)
   224  
   225  	return topicreader.NewReader(internalReader), nil
   226  }
   227  
   228  // StartWriter create new topic writer wrapper
   229  func (c *Client) StartWriter(topicPath string, opts ...topicoptions.WriterOption) (*topicwriter.Writer, error) {
   230  	var connector topicwriterinternal.ConnectFunc = func(ctx context.Context) (
   231  		topicwriterinternal.RawTopicWriterStream,
   232  		error,
   233  	) {
   234  		return c.rawClient.StreamWrite(ctx)
   235  	}
   236  
   237  	options := []topicoptions.WriterOption{
   238  		topicwriterinternal.WithConnectFunc(connector),
   239  		topicwriterinternal.WithTopic(topicPath),
   240  		topicwriterinternal.WithCommonConfig(c.cfg.Common),
   241  		topicwriterinternal.WithTrace(c.cfg.Trace),
   242  	}
   243  
   244  	options = append(options, opts...)
   245  
   246  	writer, err := topicwriterinternal.NewWriter(c.cred, options)
   247  	if err != nil {
   248  		return nil, err
   249  	}
   250  
   251  	return topicwriter.NewWriter(writer), nil
   252  }