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

     1  package coordination
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"github.com/ydb-platform/ydb-go-genproto/Ydb_Coordination_V1"
     8  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Coordination"
     9  	"google.golang.org/grpc"
    10  
    11  	"github.com/ydb-platform/ydb-go-sdk/v3/coordination"
    12  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/coordination/config"
    13  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/operation"
    14  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
    15  	"github.com/ydb-platform/ydb-go-sdk/v3/retry"
    16  	"github.com/ydb-platform/ydb-go-sdk/v3/scheme"
    17  )
    18  
    19  //nolint:gofumpt
    20  //nolint:nolintlint
    21  var (
    22  	errNilClient = xerrors.Wrap(errors.New("coordination client is not initialized"))
    23  )
    24  
    25  type Client struct {
    26  	config  config.Config
    27  	service Ydb_Coordination_V1.CoordinationServiceClient
    28  }
    29  
    30  func New(ctx context.Context, cc grpc.ClientConnInterface, config config.Config) (*Client, error) {
    31  	return &Client{
    32  		config:  config,
    33  		service: Ydb_Coordination_V1.NewCoordinationServiceClient(cc),
    34  	}, nil
    35  }
    36  
    37  func (c *Client) CreateNode(ctx context.Context, path string, config coordination.NodeConfig) error {
    38  	if c == nil {
    39  		return xerrors.WithStackTrace(errNilClient)
    40  	}
    41  	call := func(ctx context.Context) error {
    42  		return xerrors.WithStackTrace(c.createNode(ctx, path, config))
    43  	}
    44  	if !c.config.AutoRetry() {
    45  		return xerrors.WithStackTrace(call(ctx))
    46  	}
    47  
    48  	return retry.Retry(ctx,
    49  		call, retry.WithStackTrace(),
    50  		retry.WithIdempotent(true),
    51  		retry.WithTrace(c.config.TraceRetry()),
    52  	)
    53  }
    54  
    55  func (c *Client) createNode(ctx context.Context, path string, config coordination.NodeConfig) error {
    56  	_, err := c.service.CreateNode(
    57  		ctx,
    58  		&Ydb_Coordination.CreateNodeRequest{
    59  			Path: path,
    60  			Config: &Ydb_Coordination.Config{
    61  				Path:                     config.Path,
    62  				SelfCheckPeriodMillis:    config.SelfCheckPeriodMillis,
    63  				SessionGracePeriodMillis: config.SessionGracePeriodMillis,
    64  				ReadConsistencyMode:      config.ReadConsistencyMode.To(),
    65  				AttachConsistencyMode:    config.AttachConsistencyMode.To(),
    66  				RateLimiterCountersMode:  config.RatelimiterCountersMode.To(),
    67  			},
    68  			OperationParams: operation.Params(
    69  				ctx,
    70  				c.config.OperationTimeout(),
    71  				c.config.OperationCancelAfter(),
    72  				operation.ModeSync,
    73  			),
    74  		},
    75  	)
    76  
    77  	return xerrors.WithStackTrace(err)
    78  }
    79  
    80  func (c *Client) AlterNode(ctx context.Context, path string, config coordination.NodeConfig) error {
    81  	if c == nil {
    82  		return xerrors.WithStackTrace(errNilClient)
    83  	}
    84  	call := func(ctx context.Context) error {
    85  		return xerrors.WithStackTrace(c.alterNode(ctx, path, config))
    86  	}
    87  	if !c.config.AutoRetry() {
    88  		return xerrors.WithStackTrace(call(ctx))
    89  	}
    90  
    91  	return retry.Retry(ctx,
    92  		call,
    93  		retry.WithStackTrace(),
    94  		retry.WithIdempotent(true),
    95  		retry.WithTrace(c.config.TraceRetry()),
    96  	)
    97  }
    98  
    99  func (c *Client) alterNode(ctx context.Context, path string, config coordination.NodeConfig) error {
   100  	_, err := c.service.AlterNode(
   101  		ctx,
   102  		&Ydb_Coordination.AlterNodeRequest{
   103  			Path: path,
   104  			Config: &Ydb_Coordination.Config{
   105  				Path:                     config.Path,
   106  				SelfCheckPeriodMillis:    config.SelfCheckPeriodMillis,
   107  				SessionGracePeriodMillis: config.SessionGracePeriodMillis,
   108  				ReadConsistencyMode:      config.ReadConsistencyMode.To(),
   109  				AttachConsistencyMode:    config.AttachConsistencyMode.To(),
   110  				RateLimiterCountersMode:  config.RatelimiterCountersMode.To(),
   111  			},
   112  			OperationParams: operation.Params(
   113  				ctx,
   114  				c.config.OperationTimeout(),
   115  				c.config.OperationCancelAfter(),
   116  				operation.ModeSync,
   117  			),
   118  		},
   119  	)
   120  
   121  	return xerrors.WithStackTrace(err)
   122  }
   123  
   124  func (c *Client) DropNode(ctx context.Context, path string) error {
   125  	if c == nil {
   126  		return xerrors.WithStackTrace(errNilClient)
   127  	}
   128  	call := func(ctx context.Context) error {
   129  		return xerrors.WithStackTrace(c.dropNode(ctx, path))
   130  	}
   131  	if !c.config.AutoRetry() {
   132  		return xerrors.WithStackTrace(call(ctx))
   133  	}
   134  
   135  	return retry.Retry(ctx, call,
   136  		retry.WithStackTrace(),
   137  		retry.WithIdempotent(true),
   138  		retry.WithTrace(c.config.TraceRetry()),
   139  	)
   140  }
   141  
   142  func (c *Client) dropNode(ctx context.Context, path string) error {
   143  	_, err := c.service.DropNode(
   144  		ctx,
   145  		&Ydb_Coordination.DropNodeRequest{
   146  			Path: path,
   147  			OperationParams: operation.Params(
   148  				ctx,
   149  				c.config.OperationTimeout(),
   150  				c.config.OperationCancelAfter(),
   151  				operation.ModeSync,
   152  			),
   153  		},
   154  	)
   155  
   156  	return xerrors.WithStackTrace(err)
   157  }
   158  
   159  func (c *Client) DescribeNode(
   160  	ctx context.Context,
   161  	path string,
   162  ) (
   163  	entry *scheme.Entry,
   164  	config *coordination.NodeConfig,
   165  	_ error,
   166  ) {
   167  	if c == nil {
   168  		return nil, nil, xerrors.WithStackTrace(errNilClient)
   169  	}
   170  	call := func(ctx context.Context) (err error) {
   171  		entry, config, err = c.describeNode(ctx, path)
   172  
   173  		return xerrors.WithStackTrace(err)
   174  	}
   175  	if !c.config.AutoRetry() {
   176  		err := call(ctx)
   177  
   178  		return entry, config, xerrors.WithStackTrace(err)
   179  	}
   180  	err := retry.Retry(ctx, call,
   181  		retry.WithStackTrace(),
   182  		retry.WithIdempotent(true),
   183  		retry.WithTrace(c.config.TraceRetry()),
   184  	)
   185  
   186  	return entry, config, xerrors.WithStackTrace(err)
   187  }
   188  
   189  // DescribeNode describes a coordination node
   190  func (c *Client) describeNode(
   191  	ctx context.Context,
   192  	path string,
   193  ) (
   194  	_ *scheme.Entry,
   195  	_ *coordination.NodeConfig,
   196  	err error,
   197  ) {
   198  	var (
   199  		response *Ydb_Coordination.DescribeNodeResponse
   200  		result   Ydb_Coordination.DescribeNodeResult
   201  	)
   202  	response, err = c.service.DescribeNode(
   203  		ctx,
   204  		&Ydb_Coordination.DescribeNodeRequest{
   205  			Path: path,
   206  			OperationParams: operation.Params(
   207  				ctx,
   208  				c.config.OperationTimeout(),
   209  				c.config.OperationCancelAfter(),
   210  				operation.ModeSync,
   211  			),
   212  		},
   213  	)
   214  	if err != nil {
   215  		return nil, nil, xerrors.WithStackTrace(err)
   216  	}
   217  	err = response.GetOperation().GetResult().UnmarshalTo(&result)
   218  	if err != nil {
   219  		return nil, nil, xerrors.WithStackTrace(err)
   220  	}
   221  
   222  	return scheme.InnerConvertEntry(result.GetSelf()), &coordination.NodeConfig{
   223  		Path:                     result.GetConfig().GetPath(),
   224  		SelfCheckPeriodMillis:    result.GetConfig().GetSelfCheckPeriodMillis(),
   225  		SessionGracePeriodMillis: result.GetConfig().GetSessionGracePeriodMillis(),
   226  		ReadConsistencyMode:      consistencyMode(result.GetConfig().GetReadConsistencyMode()),
   227  		AttachConsistencyMode:    consistencyMode(result.GetConfig().GetAttachConsistencyMode()),
   228  		RatelimiterCountersMode:  ratelimiterCountersMode(result.GetConfig().GetRateLimiterCountersMode()),
   229  	}, nil
   230  }
   231  
   232  func (c *Client) Close(ctx context.Context) error {
   233  	if c == nil {
   234  		return xerrors.WithStackTrace(errNilClient)
   235  	}
   236  
   237  	return c.close(ctx)
   238  }
   239  
   240  func (c *Client) close(context.Context) error {
   241  	return nil
   242  }
   243  
   244  func consistencyMode(t Ydb_Coordination.ConsistencyMode) coordination.ConsistencyMode {
   245  	switch t {
   246  	case Ydb_Coordination.ConsistencyMode_CONSISTENCY_MODE_STRICT:
   247  		return coordination.ConsistencyModeStrict
   248  	case Ydb_Coordination.ConsistencyMode_CONSISTENCY_MODE_RELAXED:
   249  		return coordination.ConsistencyModeRelaxed
   250  	default:
   251  		return coordination.ConsistencyModeUnset
   252  	}
   253  }
   254  
   255  func ratelimiterCountersMode(t Ydb_Coordination.RateLimiterCountersMode) coordination.RatelimiterCountersMode {
   256  	switch t {
   257  	case Ydb_Coordination.RateLimiterCountersMode_RATE_LIMITER_COUNTERS_MODE_AGGREGATED:
   258  		return coordination.RatelimiterCountersModeAggregated
   259  	case Ydb_Coordination.RateLimiterCountersMode_RATE_LIMITER_COUNTERS_MODE_DETAILED:
   260  		return coordination.RatelimiterCountersModeDetailed
   261  	default:
   262  		return coordination.RatelimiterCountersModeUnset
   263  	}
   264  }