forked from TrueCloudLab/rclone
Fix bwlimit toggle in conjunction with schedules (Fixes #1607)
This commit is contained in:
parent
e96c5b5f39
commit
bb6300b032
2 changed files with 29 additions and 12 deletions
|
@ -18,25 +18,26 @@ import (
|
||||||
|
|
||||||
// Globals
|
// Globals
|
||||||
var (
|
var (
|
||||||
Stats = NewStats()
|
Stats = NewStats()
|
||||||
tokenBucketMu sync.Mutex // protects the token bucket variables
|
tokenBucketMu sync.Mutex // protects the token bucket variables
|
||||||
tokenBucket *rate.Limiter
|
tokenBucket *rate.Limiter
|
||||||
prevTokenBucket = tokenBucket
|
prevTokenBucket = tokenBucket
|
||||||
currLimitMu sync.Mutex // protects changes to the timeslot
|
bwLimitToggledOff = false
|
||||||
currLimit BwTimeSlot
|
currLimitMu sync.Mutex // protects changes to the timeslot
|
||||||
|
currLimit BwTimeSlot
|
||||||
)
|
)
|
||||||
|
|
||||||
const maxBurstSize = 1 * 1024 * 1024 // must be bigger than the biggest request
|
const maxBurstSize = 1 * 1024 * 1024 // must be bigger than the biggest request
|
||||||
|
|
||||||
// make a new empty token bucket with the bandwidth given
|
// make a new empty token bucket with the bandwidth given
|
||||||
func newTokenBucket(bandwidth SizeSuffix) *rate.Limiter {
|
func newTokenBucket(bandwidth SizeSuffix) *rate.Limiter {
|
||||||
tokenBucket = rate.NewLimiter(rate.Limit(bandwidth), maxBurstSize)
|
newTokenBucket := rate.NewLimiter(rate.Limit(bandwidth), maxBurstSize)
|
||||||
// empty the bucket
|
// empty the bucket
|
||||||
err := tokenBucket.WaitN(context.Background(), maxBurstSize)
|
err := newTokenBucket.WaitN(context.Background(), maxBurstSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Errorf(nil, "Failed to empty token bucket: %v", err)
|
Errorf(nil, "Failed to empty token bucket: %v", err)
|
||||||
}
|
}
|
||||||
return tokenBucket
|
return newTokenBucket
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the token bucket if necessary
|
// Start the token bucket if necessary
|
||||||
|
@ -72,12 +73,27 @@ func startTokenTicker() {
|
||||||
if currLimit.bandwidth != limitNow.bandwidth {
|
if currLimit.bandwidth != limitNow.bandwidth {
|
||||||
tokenBucketMu.Lock()
|
tokenBucketMu.Lock()
|
||||||
|
|
||||||
|
// If bwlimit is toggled off, the change should only
|
||||||
|
// become active on the next toggle, which causes
|
||||||
|
// an exchange of tokenBucket <-> prevTokenBucket
|
||||||
|
var targetBucket **rate.Limiter
|
||||||
|
if bwLimitToggledOff {
|
||||||
|
targetBucket = &prevTokenBucket
|
||||||
|
} else {
|
||||||
|
targetBucket = &tokenBucket
|
||||||
|
}
|
||||||
|
|
||||||
// Set new bandwidth. If unlimited, set tokenbucket to nil.
|
// Set new bandwidth. If unlimited, set tokenbucket to nil.
|
||||||
if limitNow.bandwidth > 0 {
|
if limitNow.bandwidth > 0 {
|
||||||
tokenBucket = newTokenBucket(limitNow.bandwidth)
|
*targetBucket = newTokenBucket(limitNow.bandwidth)
|
||||||
Logf(nil, "Scheduled bandwidth change. Limit set to %vBytes/s", &limitNow.bandwidth)
|
if bwLimitToggledOff {
|
||||||
|
Logf(nil, "Scheduled bandwidth change. " +
|
||||||
|
"Limit will be set to %vBytes/s when toggled on again.", &limitNow.bandwidth)
|
||||||
|
} else {
|
||||||
|
Logf(nil, "Scheduled bandwidth change. Limit set to %vBytes/s", &limitNow.bandwidth)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tokenBucket = nil
|
*targetBucket = nil
|
||||||
Logf(nil, "Scheduled bandwidth change. Bandwidth limits disabled")
|
Logf(nil, "Scheduled bandwidth change. Bandwidth limits disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ func startSignalHandler() {
|
||||||
for {
|
for {
|
||||||
<-signals
|
<-signals
|
||||||
tokenBucketMu.Lock()
|
tokenBucketMu.Lock()
|
||||||
|
bwLimitToggledOff = !bwLimitToggledOff
|
||||||
tokenBucket, prevTokenBucket = prevTokenBucket, tokenBucket
|
tokenBucket, prevTokenBucket = prevTokenBucket, tokenBucket
|
||||||
s := "disabled"
|
s := "disabled"
|
||||||
if tokenBucket != nil {
|
if tokenBucket != nil {
|
||||||
|
|
Loading…
Add table
Reference in a new issue