github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/coordination/coordination.go (about)

     1  package coordination
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math"
     7  	"time"
     8  
     9  	"github.com/ydb-platform/ydb-go-sdk/v3/coordination/options"
    10  	"github.com/ydb-platform/ydb-go-sdk/v3/scheme"
    11  )
    12  
    13  type Client interface {
    14  	CreateNode(ctx context.Context, path string, config NodeConfig) (err error)
    15  	AlterNode(ctx context.Context, path string, config NodeConfig) (err error)
    16  	DropNode(ctx context.Context, path string) (err error)
    17  	DescribeNode(ctx context.Context, path string) (_ *scheme.Entry, _ *NodeConfig, err error)
    18  
    19  	// Session starts a new session. This method blocks until the server session is created. The context provided
    20  	// may be used to cancel the invocation. If the method completes successfully, the session remains alive even if
    21  	// the context is canceled.
    22  	//
    23  	// To ensure resources are not leaked, one of the following actions must be performed:
    24  	//
    25  	// - call Close on the Session,
    26  	// - close the Client which the session was created with,
    27  	// - call any method of the Session until the ErrSessionClosed is returned.
    28  	//
    29  	// Experimental: https://github.com/ydb-platform/ydb-go-sdk/blob/master/VERSIONING.md#experimental
    30  	Session(ctx context.Context, path string, opts ...options.SessionOption) (Session, error)
    31  }
    32  
    33  const (
    34  	// MaxSemaphoreLimit defines the maximum value of the limit parameter in the Session.CreateSemaphore method.
    35  	MaxSemaphoreLimit = math.MaxUint64
    36  
    37  	// Exclusive is just a shortcut for the maximum semaphore limit value. You can use this to acquire a semaphore in
    38  	// the exclusive mode if it was created with the limit value of MaxSemaphoreLimit, which is always true for
    39  	// ephemeral semaphores.
    40  	Exclusive = math.MaxUint64
    41  
    42  	// Shared is just a shortcut for the minimum semaphore limit value (1). You can use this to acquire a semaphore in
    43  	// the shared mode if it was created with the limit value of MaxSemaphoreLimit, which is always true for ephemeral
    44  	// semaphores.
    45  	Shared = 1
    46  )
    47  
    48  // Session defines a coordination service backed session.
    49  //
    50  // In general, Session API is concurrency-friendly, you can safely access all of its methods concurrently.
    51  //
    52  // The client guarantees that sequential calls of the methods are sent to the server in the same order. However, the
    53  // session client may reorder and suspend some of the requests without violating correctness of the execution. This also
    54  // applies to the situations when the underlying gRPC stream has been recreated due to network or server issues.
    55  //
    56  // The client automatically keeps the underlying gRPC stream alive by sending keep-alive (ping-pong) requests. If the
    57  // client can no longer consider the session alive, it immediately cancels the session context which also leads to
    58  // cancellation of contexts of all semaphore leases created by this session.
    59  type Session interface {
    60  	// Close closes the coordination service session. It cancels all active requests on the server and notifies every
    61  	// pending or waiting for response request on the client side. It also cancels the session context and tries to
    62  	// stop the session gracefully on the server. If the ctx is canceled, this will not wait for the server session to
    63  	// become stopped and returns immediately with an error. Once this function returns with no error, all subsequent
    64  	// calls will be noop.
    65  	Close(ctx context.Context) error
    66  
    67  	// Context returns the context of the session. It is canceled when the underlying server session is over or if the
    68  	// client could not get any successful response from the server before the session timeout (see
    69  	// options.WithSessionTimeout).
    70  	Context() context.Context
    71  
    72  	// CreateSemaphore creates a new semaphore. This method waits until the server successfully creates a new semaphore
    73  	// or returns an error.
    74  	//
    75  	// This method is not idempotent. If the request has been sent to the server but no reply has been received, it
    76  	// returns the ErrOperationStatusUnknown error.
    77  	CreateSemaphore(ctx context.Context, name string, limit uint64, opts ...options.CreateSemaphoreOption) error
    78  
    79  	// UpdateSemaphore changes semaphore data. This method waits until the server successfully updates the semaphore or
    80  	// returns an error.
    81  	//
    82  	// This method is not idempotent. The client will automatically retry in the case of network or server failure
    83  	// unless it leaves the client state inconsistent.
    84  	UpdateSemaphore(ctx context.Context, name string, opts ...options.UpdateSemaphoreOption) error
    85  
    86  	// DeleteSemaphore deletes an existing semaphore. This method waits until the server successfully deletes the
    87  	// semaphore or returns an error.
    88  	//
    89  	// This method is not idempotent. If the request has been sent to the server but no reply has been received, it
    90  	// returns the ErrOperationStatusUnknown error.
    91  	DeleteSemaphore(ctx context.Context, name string, opts ...options.DeleteSemaphoreOption) error
    92  
    93  	// DescribeSemaphore returns the state of the semaphore.
    94  	//
    95  	// This method is idempotent. The client will automatically retry in the case of network or server failure.
    96  	DescribeSemaphore(
    97  		ctx context.Context,
    98  		name string,
    99  		opts ...options.DescribeSemaphoreOption,
   100  	) (*SemaphoreDescription, error)
   101  
   102  	// AcquireSemaphore acquires the semaphore. If you acquire an ephemeral semaphore (see options.WithEphemeral), its
   103  	// limit will be set to MaxSemaphoreLimit. Later requests override previous operations with the same semaphore, e.g.
   104  	// to reduce acquired count, change timeout or attached data.
   105  	//
   106  	// This method blocks until the semaphore is acquired, an error is returned from the server or the session is
   107  	// closed. If the operation context was canceled but the server replied that the semaphore was actually acquired,
   108  	// the client will automatically release the semaphore.
   109  	//
   110  	// Semaphore waiting is fair: the semaphore guarantees that other sessions invoking the AcquireSemaphore method
   111  	// acquire permits in the order which they were called (FIFO). If a session invokes the AcquireSemaphore method
   112  	// multiple times while the first invocation is still in process, the position in the queue remains unchanged.
   113  	//
   114  	// This method is idempotent. The client will automatically retry in the case of network or server failure.
   115  	AcquireSemaphore(
   116  		ctx context.Context,
   117  		name string,
   118  		count uint64,
   119  		opts ...options.AcquireSemaphoreOption,
   120  	) (Lease, error)
   121  
   122  	// SessionID returns a server-generated identifier of the session. This value is permanent and unique within the
   123  	// coordination service node.
   124  	SessionID() uint64
   125  
   126  	// Reconnect forcibly shuts down the underlying gRPC stream and initiates a new one. This method is highly unlikely
   127  	// to be of use in a typical application but is extremely useful for testing an API implementation.
   128  	Reconnect()
   129  }
   130  
   131  // Lease is the object which defines the rights of the session to the acquired semaphore. Lease is alive until its
   132  // context is not canceled. This may happen implicitly, when the associated session becomes lost or closed, or
   133  // explicitly, if someone calls the Release method of the lease.
   134  type Lease interface {
   135  	// Context returns the context of the lease. It is canceled when the session it was created by was lost or closed,
   136  	// or if the lease was released by calling the Release method.
   137  	Context() context.Context
   138  
   139  	// Release releases the acquired lease to the semaphore. It also cancels the context of the lease. This method does
   140  	// not take a ctx argument, but you can cancel the execution of it by closing the session or canceling its context.
   141  	Release() error
   142  
   143  	// Session returns the session which this lease was created by.
   144  	Session() Session
   145  }
   146  
   147  // SemaphoreDescription describes the state of a semaphore.
   148  type SemaphoreDescription struct {
   149  	// Name is the name of the semaphore.
   150  	Name string
   151  
   152  	// Limit is the maximum number of tokens that may be acquired.
   153  	Limit uint64
   154  
   155  	// Count is the number of tokens currently acquired by its owners.
   156  	Count uint64
   157  
   158  	// Ephemeral semaphores are deleted when there are no owners and waiters left.
   159  	Ephemeral bool
   160  
   161  	// Data is user-defined data attached to the semaphore.
   162  	Data []byte
   163  
   164  	// Owner is the list of current owners of the semaphore.
   165  	Owners []*SemaphoreSession
   166  
   167  	// Waiter is the list of current waiters of the semaphore.
   168  	Waiters []*SemaphoreSession
   169  }
   170  
   171  // SemaphoreSession describes an owner or a waiter of this semaphore.
   172  type SemaphoreSession struct {
   173  	// SessionID is the id of the session which tried to acquire the semaphore.
   174  	SessionID uint64
   175  
   176  	// Count is the number of tokens for the acquire operation.
   177  	Count uint64
   178  
   179  	// OrderId is a monotonically increasing id which determines locking order.
   180  	OrderID uint64
   181  
   182  	// Data is user-defined data attached to the acquire operation.
   183  	Data []byte
   184  
   185  	// Timeout is the timeout for the operation in the waiter queue. If this is time.Duration(math.MaxInt64) the session
   186  	// will wait for the semaphore until the operation is canceled.
   187  	Timeout time.Duration
   188  }
   189  
   190  func (d *SemaphoreDescription) String() string {
   191  	return fmt.Sprintf(
   192  		"{Name: %q Limit: %d Count: %d Ephemeral: %t Data: %q Owners: %s Waiters: %s}",
   193  		d.Name, d.Limit, d.Count, d.Ephemeral, d.Data, d.Owners, d.Waiters)
   194  }
   195  
   196  func (s *SemaphoreSession) String() string {
   197  	return fmt.Sprintf("{SessionID: %d Count: %d OrderID: %d Data: %q TimeoutMillis: %v}",
   198  		s.SessionID, s.Count, s.OrderID, s.Data, s.Timeout)
   199  }