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 }