Use live QUIC pressure for endpoint ranking
This commit is contained in:
@@ -54,9 +54,21 @@ type QUICFabricTransportSnapshot struct {
|
||||
MaxStreamsPerConn int `json:"max_streams_per_conn"`
|
||||
SaturatedConnections int `json:"saturated_connections"`
|
||||
CapacityPressurePercent int `json:"capacity_pressure_percent"`
|
||||
Connections []QUICFabricConnSnapshot `json:"connections,omitempty"`
|
||||
Stats QUICFabricTransportStats `json:"stats"`
|
||||
}
|
||||
|
||||
type QUICFabricConnSnapshot struct {
|
||||
PeerID string `json:"peer_id,omitempty"`
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
CertSHA256 string `json:"cert_sha256,omitempty"`
|
||||
ActiveStreams int `json:"active_streams"`
|
||||
MaxStreams int `json:"max_streams"`
|
||||
CapacityPressurePercent int `json:"capacity_pressure_percent"`
|
||||
Saturated bool `json:"saturated"`
|
||||
LastUsedUnixSec int64 `json:"last_used_unix_sec,omitempty"`
|
||||
}
|
||||
|
||||
type quicFabricSession struct {
|
||||
conn *quic.Conn
|
||||
stream *quic.Stream
|
||||
@@ -313,6 +325,20 @@ func quicFabricConnKey(target FabricTransportTarget) string {
|
||||
return peerID + "\x00" + endpoint + "\x00" + normalizeCertSHA256(target.PeerCertSHA256)
|
||||
}
|
||||
|
||||
func parseQUICFabricConnKey(key string) (peerID string, endpoint string, certSHA256 string) {
|
||||
parts := strings.SplitN(key, "\x00", 3)
|
||||
if len(parts) > 0 {
|
||||
peerID = parts[0]
|
||||
}
|
||||
if len(parts) > 1 {
|
||||
endpoint = parts[1]
|
||||
}
|
||||
if len(parts) > 2 {
|
||||
certSHA256 = parts[2]
|
||||
}
|
||||
return peerID, endpoint, certSHA256
|
||||
}
|
||||
|
||||
func (t *QUICFabricTransport) Close() error {
|
||||
if t == nil {
|
||||
return nil
|
||||
@@ -359,6 +385,22 @@ func (t *QUICFabricTransport) Snapshot() QUICFabricTransportSnapshot {
|
||||
default:
|
||||
snapshot.ActiveCount++
|
||||
snapshot.ActiveStreams += entry.activeStreams
|
||||
peerID, endpoint, certSHA256 := parseQUICFabricConnKey(key)
|
||||
connSnapshot := QUICFabricConnSnapshot{
|
||||
PeerID: peerID,
|
||||
Endpoint: endpoint,
|
||||
CertSHA256: certSHA256,
|
||||
ActiveStreams: entry.activeStreams,
|
||||
MaxStreams: limit,
|
||||
Saturated: entry.activeStreams >= limit,
|
||||
}
|
||||
if !entry.lastUsed.IsZero() {
|
||||
connSnapshot.LastUsedUnixSec = entry.lastUsed.UTC().Unix()
|
||||
}
|
||||
if limit > 0 {
|
||||
connSnapshot.CapacityPressurePercent = (entry.activeStreams * 100) / limit
|
||||
}
|
||||
snapshot.Connections = append(snapshot.Connections, connSnapshot)
|
||||
if entry.activeStreams >= limit {
|
||||
snapshot.SaturatedConnections++
|
||||
}
|
||||
|
||||
@@ -195,6 +195,13 @@ func TestQUICFabricTransportReusesConnectionForPeerEndpoint(t *testing.T) {
|
||||
if snapshot.ActiveCount != 1 || snapshot.Stats.Opens != 1 || snapshot.Stats.Reuses != 1 {
|
||||
t.Fatalf("unexpected quic transport snapshot: %+v", snapshot)
|
||||
}
|
||||
if len(snapshot.Connections) != 1 ||
|
||||
snapshot.Connections[0].PeerID != "node-b" ||
|
||||
snapshot.Connections[0].Endpoint != server.Addr().String() ||
|
||||
snapshot.Connections[0].ActiveStreams != 2 ||
|
||||
snapshot.Connections[0].MaxStreams != defaultQUICFabricMaxStreamsPerConn {
|
||||
t.Fatalf("unexpected quic connection snapshot: %+v", snapshot.Connections)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQUICFabricTransportPrunesIdleConnections(t *testing.T) {
|
||||
@@ -319,6 +326,11 @@ func TestQUICFabricTransportLimitsStreamsPerConnection(t *testing.T) {
|
||||
snapshot.Stats.StreamLimitRejects != 1 {
|
||||
t.Fatalf("unexpected stream limit snapshot: %+v", snapshot)
|
||||
}
|
||||
if len(snapshot.Connections) != 1 ||
|
||||
!snapshot.Connections[0].Saturated ||
|
||||
snapshot.Connections[0].CapacityPressurePercent != 100 {
|
||||
t.Fatalf("unexpected saturated connection snapshot: %+v", snapshot.Connections)
|
||||
}
|
||||
if err := first.Close(); err != nil {
|
||||
t.Fatalf("close first stream: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user