Port ListBuckets to websockets layer & some cleanup (#19199)

This commit is contained in:
Klaus Post
2024-03-08 20:08:18 +01:00
committed by GitHub
parent 650efc2e96
commit 51f62a8da3
15 changed files with 2783 additions and 184 deletions

View File

@@ -19,11 +19,8 @@ package cmd
import (
"context"
"encoding/gob"
"errors"
"fmt"
"io"
"net/url"
"sort"
"strconv"
"sync/atomic"
@@ -31,9 +28,7 @@ import (
"github.com/minio/madmin-go/v3"
"github.com/minio/minio/internal/grid"
xhttp "github.com/minio/minio/internal/http"
"github.com/minio/minio/internal/logger"
"github.com/minio/minio/internal/rest"
"github.com/minio/pkg/v2/sync/errgroup"
"golang.org/x/exp/slices"
)
@@ -92,39 +87,14 @@ func (l localPeerS3Client) DeleteBucket(ctx context.Context, bucket string, opts
// client to talk to peer Nodes.
type remotePeerS3Client struct {
node Node
pools []int
restClient *rest.Client
node Node
pools []int
// Function that returns the grid connection for this peer when initialized.
// Will return nil if the grid connection is not initialized yet.
gridConn func() *grid.Connection
}
// Wrapper to restClient.Call to handle network errors, in case of network error the connection is marked disconnected
// permanently. The only way to restore the connection is at the xl-sets layer by xlsets.monitorAndConnectEndpoints()
// after verifying format.json
func (client *remotePeerS3Client) call(method string, values url.Values, body io.Reader, length int64) (respBody io.ReadCloser, err error) {
return client.callWithContext(GlobalContext, method, values, body, length)
}
// Wrapper to restClient.Call to handle network errors, in case of network error the connection is marked disconnected
// permanently. The only way to restore the connection is at the xl-sets layer by xlsets.monitorAndConnectEndpoints()
// after verifying format.json
func (client *remotePeerS3Client) callWithContext(ctx context.Context, method string, values url.Values, body io.Reader, length int64) (respBody io.ReadCloser, err error) {
if values == nil {
values = make(url.Values)
}
respBody, err = client.restClient.Call(ctx, method, values, body, length)
if err == nil {
return respBody, nil
}
err = toStorageErr(err)
return nil, err
}
// S3PeerSys - S3 peer call system.
type S3PeerSys struct {
peerClients []peerS3Client // Excludes self
@@ -351,18 +321,18 @@ func (sys *S3PeerSys) GetBucketInfo(ctx context.Context, bucket string, opts Buc
}
func (client *remotePeerS3Client) ListBuckets(ctx context.Context, opts BucketOptions) ([]BucketInfo, error) {
v := url.Values{}
v.Set(peerS3BucketDeleted, strconv.FormatBool(opts.Deleted))
respBody, err := client.call(peerS3MethodListBuckets, v, nil, -1)
bi, err := listBucketsRPC.Call(ctx, client.gridConn(), &opts)
if err != nil {
return nil, err
return nil, toStorageErr(err)
}
defer xhttp.DrainBody(respBody)
var buckets []BucketInfo
err = gob.NewDecoder(respBody).Decode(&buckets)
return buckets, err
buckets := make([]BucketInfo, 0, len(bi.Value()))
for _, b := range bi.Value() {
if b != nil {
buckets = append(buckets, *b)
}
}
bi.Recycle() // BucketInfo has no internal pointers, so it's safe to recycle.
return buckets, nil
}
func (client *remotePeerS3Client) HealBucket(ctx context.Context, bucket string, opts madmin.HealOpts) (madmin.HealResultItem, error) {
@@ -533,35 +503,10 @@ func newPeerS3Clients(endpoints EndpointServerPools) (peers []peerS3Client) {
// Returns a peer S3 client.
func newPeerS3Client(node Node) peerS3Client {
scheme := "http"
if globalIsTLS {
scheme = "https"
}
serverURL := &url.URL{
Scheme: scheme,
Host: node.Host,
Path: peerS3Path,
}
restClient := rest.NewClient(serverURL, globalInternodeTransport, newCachedAuthToken())
// Use a separate client to avoid recursive calls.
healthClient := rest.NewClient(serverURL, globalInternodeTransport, newCachedAuthToken())
healthClient.NoMetrics = true
// Construct a new health function.
restClient.HealthCheckFn = func() bool {
ctx, cancel := context.WithTimeout(context.Background(), restClient.HealthCheckTimeout)
defer cancel()
respBody, err := healthClient.Call(ctx, peerS3MethodHealth, nil, nil, -1)
xhttp.DrainBody(respBody)
return !isNetworkError(err)
}
var gridConn atomic.Pointer[grid.Connection]
return &remotePeerS3Client{
node: node, restClient: restClient,
node: node,
gridConn: func() *grid.Connection {
// Lazy initialization of grid connection.
// When we create this peer client, the grid connection is likely not yet initialized.