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 }