use the actual maximum packet size in the pacer

This commit is contained in:
Marten Seemann 2021-01-25 15:03:17 +08:00
parent dd8b21f264
commit 91a314258d
4 changed files with 60 additions and 31 deletions

View file

@ -16,7 +16,7 @@ var _ = Describe("Pacer", func() {
var bandwidth uint64 // in bytes/s
BeforeEach(func() {
bandwidth = uint64(packetsPerSecond * maxDatagramSize) // 50 full-size packets per second
bandwidth = uint64(packetsPerSecond * initialMaxDatagramSize) // 50 full-size packets per second
// The pacer will multiply the bandwidth with 1.25 to achieve a slightly higher pacing speed.
// For the tests, cancel out this factor, so we can do the math using the exact bandwidth.
p = newPacer(func() Bandwidth { return Bandwidth(bandwidth) * BytesPerSecond * 4 / 5 })
@ -25,14 +25,14 @@ var _ = Describe("Pacer", func() {
It("allows a burst at the beginning", func() {
t := time.Now()
Expect(p.TimeUntilSend()).To(BeZero())
Expect(p.Budget(t)).To(BeEquivalentTo(maxBurstSize))
Expect(p.Budget(t)).To(BeEquivalentTo(maxBurstSizePackets * initialMaxDatagramSize))
})
It("allows a big burst for high pacing rates", func() {
t := time.Now()
bandwidth = uint64(10000 * packetsPerSecond * maxDatagramSize)
bandwidth = uint64(10000 * packetsPerSecond * initialMaxDatagramSize)
Expect(p.TimeUntilSend()).To(BeZero())
Expect(p.Budget(t)).To(BeNumerically(">", maxBurstSize))
Expect(p.Budget(t)).To(BeNumerically(">", maxBurstSizePackets*initialMaxDatagramSize))
})
It("reduces the budget when sending packets", func() {
@ -41,8 +41,8 @@ var _ = Describe("Pacer", func() {
for budget > 0 {
Expect(p.TimeUntilSend()).To(BeZero())
Expect(p.Budget(t)).To(Equal(budget))
p.SentPacket(t, maxDatagramSize)
budget -= maxDatagramSize
p.SentPacket(t, initialMaxDatagramSize)
budget -= initialMaxDatagramSize
}
Expect(p.Budget(t)).To(BeZero())
Expect(p.TimeUntilSend()).ToNot(BeZero())
@ -50,7 +50,7 @@ var _ = Describe("Pacer", func() {
sendBurst := func(t time.Time) {
for p.Budget(t) > 0 {
p.SentPacket(t, maxDatagramSize)
p.SentPacket(t, initialMaxDatagramSize)
}
}
@ -61,8 +61,8 @@ var _ = Describe("Pacer", func() {
for i := 0; i < 100; i++ {
t2 := p.TimeUntilSend()
Expect(t2.Sub(t)).To(BeNumerically("~", time.Second/packetsPerSecond, time.Nanosecond))
Expect(p.Budget(t2)).To(BeEquivalentTo(maxDatagramSize))
p.SentPacket(t2, maxDatagramSize)
Expect(p.Budget(t2)).To(BeEquivalentTo(initialMaxDatagramSize))
p.SentPacket(t2, initialMaxDatagramSize)
t = t2
}
})
@ -73,10 +73,10 @@ var _ = Describe("Pacer", func() {
t2 := p.TimeUntilSend()
Expect(t2.Sub(t)).To(BeNumerically("~", time.Second/packetsPerSecond, time.Nanosecond))
// send a half-full packet
Expect(p.Budget(t2)).To(BeEquivalentTo(maxDatagramSize))
size := maxDatagramSize / 2
Expect(p.Budget(t2)).To(BeEquivalentTo(initialMaxDatagramSize))
size := initialMaxDatagramSize / 2
p.SentPacket(t2, size)
Expect(p.Budget(t2)).To(Equal(maxDatagramSize - size))
Expect(p.Budget(t2)).To(Equal(initialMaxDatagramSize - size))
Expect(p.TimeUntilSend()).To(BeTemporally("~", t2.Add(time.Second/packetsPerSecond/2), time.Nanosecond))
})
@ -86,27 +86,46 @@ var _ = Describe("Pacer", func() {
t2 := p.TimeUntilSend()
Expect(t2).To(BeTemporally(">", t))
// wait for 5 times the duration
Expect(p.Budget(t.Add(5 * t2.Sub(t)))).To(BeEquivalentTo(5 * maxDatagramSize))
Expect(p.Budget(t.Add(5 * t2.Sub(t)))).To(BeEquivalentTo(5 * initialMaxDatagramSize))
})
It("accumulates budget, if no packets are sent, for larger packet sizes", func() {
t := time.Now()
sendBurst(t)
const packetSize = initialMaxDatagramSize + 200
p.SetMaxDatagramSize(packetSize)
t2 := p.TimeUntilSend()
Expect(t2).To(BeTemporally(">", t))
// wait for 5 times the duration
Expect(p.Budget(t.Add(5 * t2.Sub(t)))).To(BeEquivalentTo(5 * packetSize))
})
It("never allows bursts larger than the maximum burst size", func() {
t := time.Now()
sendBurst(t)
Expect(p.Budget(t.Add(time.Hour))).To(BeEquivalentTo(maxBurstSize))
Expect(p.Budget(t.Add(time.Hour))).To(BeEquivalentTo(maxBurstSizePackets * initialMaxDatagramSize))
})
It("never allows bursts larger than the maximum burst size, for larger packets", func() {
t := time.Now()
const packetSize = initialMaxDatagramSize + 200
p.SetMaxDatagramSize(packetSize)
sendBurst(t)
Expect(p.Budget(t.Add(time.Hour))).To(BeEquivalentTo(maxBurstSizePackets * packetSize))
})
It("changes the bandwidth", func() {
t := time.Now()
sendBurst(t)
bandwidth = uint64(5 * maxDatagramSize) // reduce the bandwidth to 5 packet per second
bandwidth = uint64(5 * initialMaxDatagramSize) // reduce the bandwidth to 5 packet per second
Expect(p.TimeUntilSend()).To(Equal(t.Add(time.Second / 5)))
})
It("doesn't pace faster than the minimum pacing duration", func() {
t := time.Now()
sendBurst(t)
bandwidth = uint64(1e6 * maxDatagramSize)
bandwidth = uint64(1e6 * initialMaxDatagramSize)
Expect(p.TimeUntilSend()).To(Equal(t.Add(protocol.MinPacingDelay)))
Expect(p.Budget(t.Add(protocol.MinPacingDelay))).To(Equal(protocol.ByteCount(protocol.MinPacingDelay) * maxDatagramSize * 1e6 / 1e9))
Expect(p.Budget(t.Add(protocol.MinPacingDelay))).To(Equal(protocol.ByteCount(protocol.MinPacingDelay) * initialMaxDatagramSize * 1e6 / 1e9))
})
})