149 lines · 4.4 KB · Go
RawDownload
// Copyright (c) 2015-2021 MinIO, Inc.//// This file is part of MinIO Object Storage stack//// This program is free software: you can redistribute it and/or modify// it under the terms of the GNU Affero General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Affero General Public License for more details.//// You should have received a copy of the GNU Affero General Public License// along with this program.  If not, see <http://www.gnu.org/licenses/>. package dsync import (	"bytes"	"context"	"errors"	"net/http"	"net/url"	"time" 	xhttp "github.com/minio/minio/internal/http"	"github.com/minio/minio/internal/rest") // ReconnectRESTClient is a wrapper type for rest.Client which provides reconnect on first failure.type ReconnectRESTClient struct {	u    *url.URL	rest *rest.Client} // newClient constructs a ReconnectRESTClient object with addr and endpoint initialized.// It _doesn't_ connect to the remote endpoint. See Call method to see when the// connect happens.func newClient(endpoint string) NetLocker {	u, err := url.Parse(endpoint)	if err != nil {		panic(err)	} 	tr := &http.Transport{		Proxy:                 http.ProxyFromEnvironment,		MaxIdleConnsPerHost:   1024,		WriteBufferSize:       32 << 10, // 32KiB moving up from 4KiB default		ReadBufferSize:        32 << 10, // 32KiB moving up from 4KiB default		IdleConnTimeout:       15 * time.Second,		ResponseHeaderTimeout: 15 * time.Minute, // Set conservative timeouts for MinIO internode.		TLSHandshakeTimeout:   15 * time.Second,		ExpectContinueTimeout: 15 * time.Second,		// Go net/http automatically unzip if content-type is		// gzip disable this feature, as we are always interested		// in raw stream.		DisableCompression: true,	} 	return &ReconnectRESTClient{		u:    u,		rest: rest.NewClient(u, tr, nil),	}} // Close closes the underlying socket file descriptor.func (restClient *ReconnectRESTClient) IsOnline() bool {	// If rest client has not connected yet there is nothing to close.	return restClient.rest != nil} func (restClient *ReconnectRESTClient) IsLocal() bool {	return false} // Close closes the underlying socket file descriptor.func (restClient *ReconnectRESTClient) Close() error {	return nil} var (	errLockConflict = errors.New("lock conflict")	errLockNotFound = errors.New("lock not found")) func toLockError(err error) error {	if err == nil {		return nil	} 	switch err.Error() {	case errLockConflict.Error():		return errLockConflict	case errLockNotFound.Error():		return errLockNotFound	}	return err} // Call makes a REST call to the remote endpoint using the msgp codecfunc (restClient *ReconnectRESTClient) Call(method string, args LockArgs) (status bool, err error) {	buf, err := args.MarshalMsg(nil)	if err != nil {		return false, err	}	body := bytes.NewReader(buf)	respBody, err := restClient.rest.Call(context.Background(), method,		url.Values{}, body, body.Size())	defer xhttp.DrainBody(respBody) 	switch toLockError(err) {	case nil:		return true, nil	case errLockConflict, errLockNotFound:		return false, nil	default:		return false, err	}} func (restClient *ReconnectRESTClient) RLock(ctx context.Context, args LockArgs) (status bool, err error) {	return restClient.Call("/v1/rlock", args)} func (restClient *ReconnectRESTClient) Lock(ctx context.Context, args LockArgs) (status bool, err error) {	return restClient.Call("/v1/lock", args)} func (restClient *ReconnectRESTClient) RUnlock(ctx context.Context, args LockArgs) (status bool, err error) {	return restClient.Call("/v1/runlock", args)} func (restClient *ReconnectRESTClient) Unlock(ctx context.Context, args LockArgs) (status bool, err error) {	return restClient.Call("/v1/unlock", args)} func (restClient *ReconnectRESTClient) Refresh(ctx context.Context, args LockArgs) (refreshed bool, err error) {	return restClient.Call("/v1/refresh", args)} func (restClient *ReconnectRESTClient) ForceUnlock(ctx context.Context, args LockArgs) (reply bool, err error) {	return restClient.Call("/v1/force-unlock", args)} func (restClient *ReconnectRESTClient) String() string {	return restClient.u.String()}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t