92 lines
2.5 KiB
Go
92 lines
2.5 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/QuantumNous/new-api/logger"
|
|
"github.com/QuantumNous/new-api/relaykit/dto"
|
|
)
|
|
|
|
// HTTPTransportPolicy is the runtime-normalized outbound HTTP transport policy
|
|
// for a channel. Unknown or out-of-range stored values are clamped safely.
|
|
type HTTPTransportPolicy struct {
|
|
Protocol string // dto.HTTPProtocolAuto or dto.HTTPProtocolHTTP1
|
|
Shards int // 1..dto.MaxHTTP2ConnectionShards
|
|
}
|
|
|
|
var httpTransportPolicyWarnings sync.Map
|
|
|
|
func defaultHTTPTransportPolicy() HTTPTransportPolicy {
|
|
return HTTPTransportPolicy{
|
|
Protocol: dto.HTTPProtocolAuto,
|
|
Shards: 1,
|
|
}
|
|
}
|
|
|
|
// NormalizeHTTPTransportPolicy converts channel settings into a safe runtime policy.
|
|
// Invalid stored values never panic; they clamp to defaults and warn once per bad value.
|
|
func NormalizeHTTPTransportPolicy(settings dto.ChannelSettings) HTTPTransportPolicy {
|
|
policy := defaultHTTPTransportPolicy()
|
|
|
|
protocol := strings.ToLower(strings.TrimSpace(settings.HTTPProtocol))
|
|
switch protocol {
|
|
case "", dto.HTTPProtocolAuto:
|
|
policy.Protocol = dto.HTTPProtocolAuto
|
|
case dto.HTTPProtocolHTTP1:
|
|
policy.Protocol = dto.HTTPProtocolHTTP1
|
|
default:
|
|
warnHTTPTransportPolicyOnce("http_protocol", settings.HTTPProtocol)
|
|
policy.Protocol = dto.HTTPProtocolAuto
|
|
}
|
|
|
|
shards := settings.HTTP2ConnectionShards
|
|
switch {
|
|
case shards == 0:
|
|
policy.Shards = 1
|
|
case shards < 1:
|
|
warnHTTPTransportPolicyOnce("http2_connection_shards", fmt.Sprintf("%d", shards))
|
|
policy.Shards = 1
|
|
case shards > dto.MaxHTTP2ConnectionShards:
|
|
warnHTTPTransportPolicyOnce("http2_connection_shards", fmt.Sprintf("%d", shards))
|
|
policy.Shards = dto.MaxHTTP2ConnectionShards
|
|
default:
|
|
policy.Shards = shards
|
|
}
|
|
|
|
if policy.Protocol == dto.HTTPProtocolHTTP1 {
|
|
if settings.HTTP2ConnectionShards > 1 {
|
|
warnHTTPTransportPolicyOnce(
|
|
"http_protocol+http2_connection_shards",
|
|
fmt.Sprintf("%s+%d", dto.HTTPProtocolHTTP1, settings.HTTP2ConnectionShards),
|
|
)
|
|
}
|
|
policy.Shards = 1
|
|
}
|
|
if policy.Shards < 1 {
|
|
policy.Shards = 1
|
|
}
|
|
return policy
|
|
}
|
|
|
|
func warnHTTPTransportPolicyOnce(field, value string) {
|
|
key := field + "=" + value
|
|
if _, loaded := httpTransportPolicyWarnings.LoadOrStore(key, struct{}{}); loaded {
|
|
return
|
|
}
|
|
logger.LogWarn(
|
|
context.Background(),
|
|
fmt.Sprintf("invalid channel http transport setting clamped: %s=%q", field, value),
|
|
)
|
|
}
|
|
|
|
func (p HTTPTransportPolicy) cacheKeyPart() string {
|
|
return fmt.Sprintf("%s|%d", p.Protocol, p.Shards)
|
|
}
|
|
|
|
func (p HTTPTransportPolicy) String() string {
|
|
return p.cacheKeyPart()
|
|
}
|