parent
0d7a57fa9d
commit
62266010ac
11 changed files with 63 additions and 20 deletions
|
@ -136,21 +136,21 @@ func (p *Proxy) ExtraDelayHistory() map[string][]C.DelayHistory {
|
|||
// LastDelay return last history record. if proxy is not alive, return the max value of uint16.
|
||||
// implements C.Proxy
|
||||
func (p *Proxy) LastDelay() (delay uint16) {
|
||||
var maxDelay uint16 = 0xffff
|
||||
var max uint16 = 0xffff
|
||||
if !p.alive.Load() {
|
||||
return maxDelay
|
||||
return max
|
||||
}
|
||||
|
||||
history := p.history.Last()
|
||||
if history.Delay == 0 {
|
||||
return maxDelay
|
||||
return max
|
||||
}
|
||||
return history.Delay
|
||||
}
|
||||
|
||||
// LastDelayForTestUrl implements C.Proxy
|
||||
func (p *Proxy) LastDelayForTestUrl(url string) (delay uint16) {
|
||||
var maxDelay uint16 = 0xffff
|
||||
var max uint16 = 0xffff
|
||||
|
||||
alive := p.alive.Load()
|
||||
history := p.history.Last()
|
||||
|
@ -161,11 +161,11 @@ func (p *Proxy) LastDelayForTestUrl(url string) (delay uint16) {
|
|||
}
|
||||
|
||||
if !alive {
|
||||
return maxDelay
|
||||
return max
|
||||
}
|
||||
|
||||
if history.Delay == 0 {
|
||||
return maxDelay
|
||||
return max
|
||||
}
|
||||
return history.Delay
|
||||
}
|
||||
|
|
|
@ -85,16 +85,16 @@ func TestObservable_UnSubscribeWithNotExistSubscription(t *testing.T) {
|
|||
func TestObservable_SubscribeGoroutineLeak(t *testing.T) {
|
||||
iter := iterator[int]([]int{1, 2, 3, 4, 5})
|
||||
src := NewObservable[int](iter)
|
||||
total := 100
|
||||
max := 100
|
||||
|
||||
var list []Subscription[int]
|
||||
for i := 0; i < total; i++ {
|
||||
for i := 0; i < max; i++ {
|
||||
ch, _ := src.Subscribe()
|
||||
list = append(list, ch)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(total)
|
||||
wg.Add(max)
|
||||
waitCh := func(ch <-chan int) {
|
||||
for range ch {
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -1,6 +1,6 @@
|
|||
module github.com/Dreamacro/clash
|
||||
|
||||
go 1.21
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/3andne/restls-client-go v0.1.6
|
||||
|
|
|
@ -3,6 +3,8 @@ package updater
|
|||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
// LimitReachedError records the limit and the operation that caused it.
|
||||
|
@ -33,7 +35,7 @@ func (lr *limitedReader) Read(p []byte) (n int, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
p = p[:min(lr.n, int64(len(p)))]
|
||||
p = p[:Min(lr.n, int64(len(p)))]
|
||||
|
||||
n, err = lr.r.Read(p)
|
||||
lr.n -= int64(n)
|
||||
|
@ -54,3 +56,12 @@ func LimitReader(r io.Reader, n int64) (limited io.Reader, err error) {
|
|||
n: n,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Min returns the smaller of x or y.
|
||||
func Min[T constraints.Integer | ~string](x, y T) (res T) {
|
||||
if x < y {
|
||||
return x
|
||||
}
|
||||
|
||||
return y
|
||||
}
|
||||
|
|
|
@ -186,7 +186,7 @@ func (c *Cubic) CongestionWindowAfterAck(
|
|||
targetCongestionWindow = c.originPointCongestionWindow - deltaCongestionWindow
|
||||
}
|
||||
// Limit the CWND increase to half the acked bytes.
|
||||
targetCongestionWindow = min(targetCongestionWindow, currentCongestionWindow+c.ackedBytesCount/2)
|
||||
targetCongestionWindow = Min(targetCongestionWindow, currentCongestionWindow+c.ackedBytesCount/2)
|
||||
|
||||
// Increase the window by approximately Alpha * 1 MSS of bytes every
|
||||
// time we ack an estimated tcp window of bytes. For small
|
||||
|
|
|
@ -177,7 +177,7 @@ func (c *cubicSender) OnPacketAcked(
|
|||
priorInFlight congestion.ByteCount,
|
||||
eventTime time.Time,
|
||||
) {
|
||||
c.largestAckedPacketNumber = max(ackedPacketNumber, c.largestAckedPacketNumber)
|
||||
c.largestAckedPacketNumber = Max(ackedPacketNumber, c.largestAckedPacketNumber)
|
||||
if c.InRecovery() {
|
||||
return
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ func (c *cubicSender) maybeIncreaseCwnd(
|
|||
c.numAckedPackets = 0
|
||||
}
|
||||
} else {
|
||||
c.congestionWindow = min(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime))
|
||||
c.congestionWindow = Min(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -74,8 +74,8 @@ func (s *HybridSlowStart) ShouldExitSlowStart(latestRTT time.Duration, minRTT ti
|
|||
// Divide minRTT by 8 to get a rtt increase threshold for exiting.
|
||||
minRTTincreaseThresholdUs := int64(minRTT / time.Microsecond >> hybridStartDelayFactorExp)
|
||||
// Ensure the rtt threshold is never less than 2ms or more than 16ms.
|
||||
minRTTincreaseThresholdUs = min(minRTTincreaseThresholdUs, hybridStartDelayMaxThresholdUs)
|
||||
minRTTincreaseThreshold := time.Duration(max(minRTTincreaseThresholdUs, hybridStartDelayMinThresholdUs)) * time.Microsecond
|
||||
minRTTincreaseThresholdUs = Min(minRTTincreaseThresholdUs, hybridStartDelayMaxThresholdUs)
|
||||
minRTTincreaseThreshold := time.Duration(Max(minRTTincreaseThresholdUs, hybridStartDelayMinThresholdUs)) * time.Microsecond
|
||||
|
||||
if s.currentMinRTT > (minRTT + minRTTincreaseThreshold) {
|
||||
s.hystartFound = true
|
||||
|
|
|
@ -16,7 +16,7 @@ func MinNonZeroDuration(a, b time.Duration) time.Duration {
|
|||
if b == 0 {
|
||||
return a
|
||||
}
|
||||
return min(a, b)
|
||||
return Min(a, b)
|
||||
}
|
||||
|
||||
// AbsDuration returns the absolute value of a time duration
|
||||
|
|
19
transport/tuic/congestion/minmax_go120.go
Normal file
19
transport/tuic/congestion/minmax_go120.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
//go:build !go1.21
|
||||
|
||||
package congestion
|
||||
|
||||
import "golang.org/x/exp/constraints"
|
||||
|
||||
func Max[T constraints.Ordered](a, b T) T {
|
||||
if a < b {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func Min[T constraints.Ordered](a, b T) T {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
13
transport/tuic/congestion/minmax_go121.go
Normal file
13
transport/tuic/congestion/minmax_go121.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
//go:build go1.21
|
||||
|
||||
package congestion
|
||||
|
||||
import "cmp"
|
||||
|
||||
func Max[T cmp.Ordered](a, b T) T {
|
||||
return max(a, b)
|
||||
}
|
||||
|
||||
func Min[T cmp.Ordered](a, b T) T {
|
||||
return min(a, b)
|
||||
}
|
|
@ -52,11 +52,11 @@ func (p *pacer) Budget(now time.Time) congestion.ByteCount {
|
|||
return p.maxBurstSize()
|
||||
}
|
||||
budget := p.budgetAtLastSent + (congestion.ByteCount(p.getAdjustedBandwidth())*congestion.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9
|
||||
return min(p.maxBurstSize(), budget)
|
||||
return Min(p.maxBurstSize(), budget)
|
||||
}
|
||||
|
||||
func (p *pacer) maxBurstSize() congestion.ByteCount {
|
||||
return max(
|
||||
return Max(
|
||||
congestion.ByteCount(uint64((MinPacingDelay+TimerGranularity).Nanoseconds())*p.getAdjustedBandwidth())/1e9,
|
||||
maxBurstSizePackets*p.maxDatagramSize,
|
||||
)
|
||||
|
@ -68,7 +68,7 @@ func (p *pacer) TimeUntilSend() time.Time {
|
|||
if p.budgetAtLastSent >= p.maxDatagramSize {
|
||||
return time.Time{}
|
||||
}
|
||||
return p.lastSentTime.Add(max(
|
||||
return p.lastSentTime.Add(Max(
|
||||
MinPacingDelay,
|
||||
time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/float64(p.getAdjustedBandwidth())))*time.Nanosecond,
|
||||
))
|
||||
|
|
Loading…
Reference in a new issue