feat: pacer code improvements

This commit is contained in:
Toby 2024-04-14 15:07:43 -07:00
parent 234dc4508b
commit 2408301c98

View File

@ -1,7 +1,6 @@
package common package common
import ( import (
"math"
"time" "time"
"github.com/apernet/quic-go/congestion" "github.com/apernet/quic-go/congestion"
@ -9,6 +8,7 @@ import (
const ( const (
maxBurstPackets = 10 maxBurstPackets = 10
maxBurstPacingDelayMultiplier = 4
) )
// Pacer implements a token bucket pacing algorithm. // Pacer implements a token bucket pacing algorithm.
@ -46,12 +46,12 @@ func (p *Pacer) Budget(now time.Time) congestion.ByteCount {
if budget < 0 { // protect against overflows if budget < 0 { // protect against overflows
budget = congestion.ByteCount(1<<62 - 1) budget = congestion.ByteCount(1<<62 - 1)
} }
return minByteCount(p.maxBurstSize(), budget) return min(p.maxBurstSize(), budget)
} }
func (p *Pacer) maxBurstSize() congestion.ByteCount { func (p *Pacer) maxBurstSize() congestion.ByteCount {
return maxByteCount( return max(
congestion.ByteCount((congestion.MinPacingDelay+time.Millisecond).Nanoseconds())*p.getBandwidth()/1e9, congestion.ByteCount((maxBurstPacingDelayMultiplier*congestion.MinPacingDelay).Nanoseconds())*p.getBandwidth()/1e9,
maxBurstPackets*p.maxDatagramSize, maxBurstPackets*p.maxDatagramSize,
) )
} }
@ -62,34 +62,18 @@ func (p *Pacer) TimeUntilSend() time.Time {
if p.budgetAtLastSent >= p.maxDatagramSize { if p.budgetAtLastSent >= p.maxDatagramSize {
return time.Time{} return time.Time{}
} }
return p.lastSentTime.Add(maxDuration( diff := 1e9 * uint64(p.maxDatagramSize-p.budgetAtLastSent)
congestion.MinPacingDelay, bw := uint64(p.getBandwidth())
time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/ // We might need to round up this value.
float64(p.getBandwidth())))*time.Nanosecond, // Otherwise, we might have a budget (slightly) smaller than the datagram size when the timer expires.
)) d := diff / bw
// this is effectively a math.Ceil, but using only integer math
if diff%bw > 0 {
d++
}
return p.lastSentTime.Add(max(congestion.MinPacingDelay, time.Duration(d)*time.Nanosecond))
} }
func (p *Pacer) SetMaxDatagramSize(s congestion.ByteCount) { func (p *Pacer) SetMaxDatagramSize(s congestion.ByteCount) {
p.maxDatagramSize = s p.maxDatagramSize = s
} }
func maxByteCount(a, b congestion.ByteCount) congestion.ByteCount {
if a < b {
return b
}
return a
}
func minByteCount(a, b congestion.ByteCount) congestion.ByteCount {
if a < b {
return a
}
return b
}
func maxDuration(a, b time.Duration) time.Duration {
if a > b {
return a
}
return b
}