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 }