github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/backend/seafile/pacer.go (about)

     1  package seafile
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"sync"
     7  	"time"
     8  
     9  	"github.com/rclone/rclone/fs"
    10  	"github.com/rclone/rclone/lib/pacer"
    11  )
    12  
    13  const (
    14  	minSleep      = 100 * time.Millisecond
    15  	maxSleep      = 10 * time.Second
    16  	decayConstant = 2 // bigger for slower decay, exponential
    17  )
    18  
    19  // Use only one pacer per server URL
    20  var (
    21  	pacers     map[string]*fs.Pacer
    22  	pacerMutex sync.Mutex
    23  )
    24  
    25  func init() {
    26  	pacers = make(map[string]*fs.Pacer, 0)
    27  }
    28  
    29  // getPacer returns the unique pacer for that remote URL
    30  func getPacer(remote string) *fs.Pacer {
    31  	pacerMutex.Lock()
    32  	defer pacerMutex.Unlock()
    33  
    34  	remote = parseRemote(remote)
    35  	if existing, found := pacers[remote]; found {
    36  		return existing
    37  	}
    38  
    39  	pacers[remote] = fs.NewPacer(
    40  		pacer.NewDefault(
    41  			pacer.MinSleep(minSleep),
    42  			pacer.MaxSleep(maxSleep),
    43  			pacer.DecayConstant(decayConstant),
    44  		),
    45  	)
    46  	return pacers[remote]
    47  }
    48  
    49  // parseRemote formats a remote url into "hostname:port"
    50  func parseRemote(remote string) string {
    51  	remoteURL, err := url.Parse(remote)
    52  	if err != nil {
    53  		// Return a default value in the very unlikely event we're not going to parse remote
    54  		fs.Infof(nil, "Cannot parse remote %s", remote)
    55  		return "default"
    56  	}
    57  	host := remoteURL.Hostname()
    58  	port := remoteURL.Port()
    59  	if port == "" {
    60  		if remoteURL.Scheme == "https" {
    61  			port = "443"
    62  		} else {
    63  			port = "80"
    64  		}
    65  	}
    66  	return fmt.Sprintf("%s:%s", host, port)
    67  }