mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 13:26:11 +08:00
accounting: fix maximum bwlimit by scaling scale max token bucket size
Before this fix, on Windows, the --bwlimit would max out at 2.5Gbps even when set to 10 Gbps. This turned out to be because of the maximum token bucket size. This fix scales up the token bucket size linearly above a bwlimit of 2Gbps. Fixes #5507
This commit is contained in:
parent
a5f277f47e
commit
33ddd540b6
|
@ -53,33 +53,45 @@ func (bs *buckets) _setOff() {
|
|||
}
|
||||
}
|
||||
|
||||
const maxBurstSize = 4 * 1024 * 1024 // must be bigger than the biggest request
|
||||
const defaultMaxBurstSize = 4 * 1024 * 1024 // must be bigger than the biggest request
|
||||
|
||||
// make a new empty token bucket with the bandwidth given
|
||||
func newEmptyTokenBucket(bandwidth fs.SizeSuffix) *rate.Limiter {
|
||||
// Relate maxBurstSize to bandwidth limit
|
||||
// 4M gives 2.5 Gb/s on Windows
|
||||
// Use defaultMaxBurstSize up to 2GBit/s (256MByte/s) then scale
|
||||
maxBurstSize := (bandwidth * defaultMaxBurstSize) / (256 * 1024 * 1024)
|
||||
if maxBurstSize < defaultMaxBurstSize {
|
||||
maxBurstSize = defaultMaxBurstSize
|
||||
}
|
||||
// fs.Debugf(nil, "bandwidth=%v maxBurstSize=%v", bandwidth, maxBurstSize)
|
||||
tb := rate.NewLimiter(rate.Limit(bandwidth), int(maxBurstSize))
|
||||
if tb != nil {
|
||||
// empty the bucket
|
||||
err := tb.WaitN(context.Background(), int(maxBurstSize))
|
||||
if err != nil {
|
||||
fs.Errorf(nil, "Failed to empty token bucket: %v", err)
|
||||
}
|
||||
}
|
||||
return tb
|
||||
}
|
||||
|
||||
// make a new empty token bucket with the bandwidth(s) given
|
||||
func newTokenBucket(bandwidth fs.BwPair) (tbs buckets) {
|
||||
bandwidthAccounting := fs.SizeSuffix(-1)
|
||||
if bandwidth.Tx > 0 {
|
||||
tbs[TokenBucketSlotTransportTx] = rate.NewLimiter(rate.Limit(bandwidth.Tx), maxBurstSize)
|
||||
tbs[TokenBucketSlotTransportTx] = newEmptyTokenBucket(bandwidth.Tx)
|
||||
bandwidthAccounting = bandwidth.Tx
|
||||
}
|
||||
if bandwidth.Rx > 0 {
|
||||
tbs[TokenBucketSlotTransportRx] = rate.NewLimiter(rate.Limit(bandwidth.Rx), maxBurstSize)
|
||||
tbs[TokenBucketSlotTransportRx] = newEmptyTokenBucket(bandwidth.Rx)
|
||||
if bandwidth.Rx > bandwidthAccounting {
|
||||
bandwidthAccounting = bandwidth.Rx
|
||||
}
|
||||
}
|
||||
// Limit core bandwidth to max of Rx and Tx if both are limited
|
||||
if bandwidth.Tx > 0 && bandwidth.Rx > 0 {
|
||||
tbs[TokenBucketSlotAccounting] = rate.NewLimiter(rate.Limit(bandwidthAccounting), maxBurstSize)
|
||||
}
|
||||
for _, tb := range tbs {
|
||||
if tb != nil {
|
||||
// empty the bucket
|
||||
err := tb.WaitN(context.Background(), maxBurstSize)
|
||||
if err != nil {
|
||||
fs.Errorf(nil, "Failed to empty token bucket: %v", err)
|
||||
}
|
||||
}
|
||||
tbs[TokenBucketSlotAccounting] = newEmptyTokenBucket(bandwidthAccounting)
|
||||
}
|
||||
return tbs
|
||||
}
|
||||
|
@ -92,7 +104,7 @@ func (tb *tokenBucket) StartTokenBucket(ctx context.Context) {
|
|||
tb.currLimit = ci.BwLimit.LimitAt(time.Now())
|
||||
if tb.currLimit.Bandwidth.IsSet() {
|
||||
tb.curr = newTokenBucket(tb.currLimit.Bandwidth)
|
||||
fs.Infof(nil, "Starting bandwidth limiter at %v Byte/s", &tb.currLimit.Bandwidth)
|
||||
fs.Infof(nil, "Starting bandwidth limiter at %vByte/s", &tb.currLimit.Bandwidth)
|
||||
|
||||
// Start the SIGUSR2 signal handler to toggle bandwidth.
|
||||
// This function does nothing in windows systems.
|
||||
|
|
Loading…
Reference in New Issue
Block a user