perf: expand gateway capacity and prevent receipt replay

This commit is contained in:
hectorzhao
2026-08-25 16:08:30 +08:00
parent 761c123b65
commit 9292352be1
48 changed files with 2001 additions and 144 deletions
+54 -5
View File
@@ -45,11 +45,20 @@ func (p *connectionPool) tryAcquireConnection() (*connection, func()) {
if len(p.conns) == 0 {
return nil, nil
}
for i := 0; i < len(p.conns); i++ {
index := (p.next + i) % len(p.conns)
conn := p.conns[index]
bestIndex := -1
bestInFlight := int(^uint(0) >> 1)
var bestRTT time.Duration
for index, conn := range p.conns {
inFlight, rtt, usable := conn.capacitySnapshot()
if !usable || inFlight > bestInFlight || (inFlight == bestInFlight && bestIndex >= 0 && bestRTT > 0 && rtt >= bestRTT) {
continue
}
bestIndex, bestInFlight, bestRTT = index, inFlight, rtt
}
if bestIndex >= 0 {
conn := p.conns[bestIndex]
if conn.tryAcquireWindow() {
p.next = (index + 1) % len(p.conns)
p.next = (bestIndex + 1) % len(p.conns)
return conn, conn.releaseWindow
}
}
@@ -57,8 +66,17 @@ func (p *connectionPool) tryAcquireConnection() (*connection, func()) {
}
func (c *connection) tryAcquireWindow() bool {
c.mu.Lock()
defer c.mu.Unlock()
if c.window == nil {
c.window = make(chan struct{}, defaultWindowSize)
c.window = make(chan struct{}, maximumWindowSize)
}
limit := c.windowLimit
if limit < 1 {
limit = defaultWindowSize
}
if c.closed || c.draining || c.client == nil || len(c.window) >= limit {
return false
}
select {
case c.window <- struct{}{}:
@@ -68,6 +86,37 @@ func (c *connection) tryAcquireWindow() bool {
}
}
func (c *connection) capacitySnapshot() (int, time.Duration, bool) {
c.mu.Lock()
defer c.mu.Unlock()
limit := c.windowLimit
if limit < 1 {
limit = defaultWindowSize
}
inFlight := len(c.window)
return inFlight, c.lastSubmitRTT, !c.closed && !c.draining && c.client != nil && inFlight < limit && !time.Now().Before(c.cooldownUntil)
}
func (c *connection) markSubmitFailure() {
c.mu.Lock()
defer c.mu.Unlock()
c.consecutiveFailures++
if c.consecutiveFailures >= 3 {
seconds := c.config.FailureCooldownSeconds
if seconds <= 0 {
seconds = 30
}
c.cooldownUntil = time.Now().Add(time.Duration(seconds) * time.Second)
}
}
func (c *connection) markSubmitSuccess() {
c.mu.Lock()
defer c.mu.Unlock()
c.consecutiveFailures = 0
c.cooldownUntil = time.Time{}
}
func (c *connection) releaseWindow() {
if c.window == nil {
return