github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/lock-rest-client.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"context"
    22  	"errors"
    23  
    24  	"github.com/minio/minio/internal/dsync"
    25  	"github.com/minio/minio/internal/grid"
    26  )
    27  
    28  // lockRESTClient is authenticable lock REST client
    29  type lockRESTClient struct {
    30  	connection *grid.Connection
    31  }
    32  
    33  // IsOnline - returns whether REST client failed to connect or not.
    34  func (c *lockRESTClient) IsOnline() bool {
    35  	return c.connection.State() == grid.StateConnected
    36  }
    37  
    38  // Not a local locker
    39  func (c *lockRESTClient) IsLocal() bool {
    40  	return false
    41  }
    42  
    43  // Close - marks the client as closed.
    44  func (c *lockRESTClient) Close() error {
    45  	return nil
    46  }
    47  
    48  // String - returns the remote host of the connection.
    49  func (c *lockRESTClient) String() string {
    50  	return c.connection.Remote
    51  }
    52  
    53  func (c *lockRESTClient) call(ctx context.Context, h *grid.SingleHandler[*dsync.LockArgs, *dsync.LockResp], args *dsync.LockArgs) (ok bool, err error) {
    54  	r, err := h.Call(ctx, c.connection, args)
    55  	if err != nil {
    56  		return false, err
    57  	}
    58  	defer h.PutResponse(r)
    59  	ok = r.Code == dsync.RespOK
    60  	switch r.Code {
    61  	case dsync.RespLockConflict, dsync.RespLockNotFound, dsync.RespOK:
    62  	// no error
    63  	case dsync.RespLockNotInitialized:
    64  		err = errLockNotInitialized
    65  	default:
    66  		err = errors.New(r.Err)
    67  	}
    68  	return ok, err
    69  }
    70  
    71  // RLock calls read lock REST API.
    72  func (c *lockRESTClient) RLock(ctx context.Context, args dsync.LockArgs) (reply bool, err error) {
    73  	return c.call(ctx, lockRPCRLock, &args)
    74  }
    75  
    76  // Lock calls lock REST API.
    77  func (c *lockRESTClient) Lock(ctx context.Context, args dsync.LockArgs) (reply bool, err error) {
    78  	return c.call(ctx, lockRPCLock, &args)
    79  }
    80  
    81  // RUnlock calls read unlock REST API.
    82  func (c *lockRESTClient) RUnlock(ctx context.Context, args dsync.LockArgs) (reply bool, err error) {
    83  	return c.call(ctx, lockRPCRUnlock, &args)
    84  }
    85  
    86  // Refresh calls Refresh REST API.
    87  func (c *lockRESTClient) Refresh(ctx context.Context, args dsync.LockArgs) (reply bool, err error) {
    88  	return c.call(ctx, lockRPCRefresh, &args)
    89  }
    90  
    91  // Unlock calls write unlock RPC.
    92  func (c *lockRESTClient) Unlock(ctx context.Context, args dsync.LockArgs) (reply bool, err error) {
    93  	return c.call(ctx, lockRPCUnlock, &args)
    94  }
    95  
    96  // ForceUnlock calls force unlock handler to forcibly unlock an active lock.
    97  func (c *lockRESTClient) ForceUnlock(ctx context.Context, args dsync.LockArgs) (reply bool, err error) {
    98  	return c.call(ctx, lockRPCForceUnlock, &args)
    99  }
   100  
   101  func newLockAPI(endpoint Endpoint) dsync.NetLocker {
   102  	if endpoint.IsLocal {
   103  		return globalLockServer
   104  	}
   105  	return newlockRESTClient(endpoint)
   106  }
   107  
   108  // Returns a lock rest client.
   109  func newlockRESTClient(ep Endpoint) *lockRESTClient {
   110  	return &lockRESTClient{globalGrid.Load().Connection(ep.GridHost())}
   111  }