mirror of
https://github.com/traefik/traefik.git
synced 2026-02-18 18:20:28 -05:00
Merge v3.6 into master
Some checks failed
CodeQL / Analyze (push) Has been cancelled
Build and Publish Documentation / Doc Process (push) Has been cancelled
Build experimental image on branch / build-webui (push) Has been cancelled
Build experimental image on branch / Build experimental image on branch (push) Has been cancelled
Some checks failed
CodeQL / Analyze (push) Has been cancelled
Build and Publish Documentation / Doc Process (push) Has been cancelled
Build experimental image on branch / build-webui (push) Has been cancelled
Build experimental image on branch / Build experimental image on branch (push) Has been cancelled
This commit is contained in:
commit
4a4be524bb
24 changed files with 93 additions and 94 deletions
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
|
|
@ -10,7 +10,7 @@ on:
|
|||
- 'script/gcg/**'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.24'
|
||||
GO_VERSION: '1.25'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
|
|
|
|||
2
.github/workflows/experimental.yaml
vendored
2
.github/workflows/experimental.yaml
vendored
|
|
@ -7,7 +7,7 @@ on:
|
|||
- v*
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.24'
|
||||
GO_VERSION: '1.25'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
|
|
|
|||
6
.github/workflows/release.yaml
vendored
6
.github/workflows/release.yaml
vendored
|
|
@ -6,7 +6,7 @@ on:
|
|||
- 'v*.*.*'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.24'
|
||||
GO_VERSION: '1.25'
|
||||
CGO_ENABLED: 0
|
||||
VERSION: ${{ github.ref_name }}
|
||||
TRAEFIKER_EMAIL: "traefiker@traefik.io"
|
||||
|
|
@ -130,8 +130,8 @@ jobs:
|
|||
--exclude .idea \
|
||||
--exclude .github \
|
||||
--exclude dist .
|
||||
|
||||
|
||||
chown -R "$(id -u)":"$(id -g)" dist/
|
||||
gh release create ${VERSION} ./dist/**/traefik*.{zip,tar.gz} ./dist/traefik*.{tar.gz,txt} --repo traefik/traefik --title ${VERSION} --notes ${VERSION} --latest=false
|
||||
|
||||
|
||||
./script/deploy.sh
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ on:
|
|||
- 'integration/integration_test.go'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.24'
|
||||
GO_VERSION: '1.25'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
|
|
|
|||
2
.github/workflows/test-integration.yaml
vendored
2
.github/workflows/test-integration.yaml
vendored
|
|
@ -10,7 +10,7 @@ on:
|
|||
- 'script/gcg/**'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.24'
|
||||
GO_VERSION: '1.25'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ on:
|
|||
- 'integration/integration_test.go'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.24'
|
||||
GO_VERSION: '1.25'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
|
|
|
|||
2
.github/workflows/test-unit.yaml
vendored
2
.github/workflows/test-unit.yaml
vendored
|
|
@ -10,7 +10,7 @@ on:
|
|||
- 'script/gcg/**'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.24'
|
||||
GO_VERSION: '1.25'
|
||||
|
||||
jobs:
|
||||
generate-packages:
|
||||
|
|
|
|||
2
.github/workflows/validate.yaml
vendored
2
.github/workflows/validate.yaml
vendored
|
|
@ -6,7 +6,7 @@ on:
|
|||
- '*'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.24'
|
||||
GO_VERSION: '1.25'
|
||||
GOLANGCI_LINT_VERSION: v2.8.0
|
||||
MISSPELL_VERSION: v0.7.0
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ tracing: {}
|
|||
| <a id="opt-tracing-addInternals" href="#opt-tracing-addInternals" title="#opt-tracing-addInternals">`tracing.addInternals`</a> | Enables tracing for internal resources (e.g.: `ping@internal`). | false | No |
|
||||
| <a id="opt-tracing-serviceName" href="#opt-tracing-serviceName" title="#opt-tracing-serviceName">`tracing.serviceName`</a> | Defines the service name resource attribute. | "traefik" | No |
|
||||
| <a id="opt-tracing-resourceAttributes" href="#opt-tracing-resourceAttributes" title="#opt-tracing-resourceAttributes">`tracing.resourceAttributes`</a> | Defines additional resource attributes to be sent to the collector. See [resourceAttributes](#resourceattributes) for details. | [] | No |
|
||||
| <a id="opt-tracing-sampleRate" href="#opt-tracing-sampleRate" title="#opt-tracing-sampleRate">`tracing.sampleRate`</a> | The proportion of requests to trace, specified between 0.0 and 1.0. | 1.0 | No |
|
||||
| <a id="opt-tracing-sampleRate" href="#opt-tracing-sampleRate" title="#opt-tracing-sampleRate">`tracing.sampleRate`</a> | The proportion of requests to trace, specified between 0.0 and 1.0.<br /> Since Traefik supports parent-based sampling ratios, root spans (i.e., spans initiated by Traefik) are sampled according to this rate, while child spans inherit the sampling decision of their parent (i.e., the tracing context from incoming requests). See [sampleRate](#samplerate) for details. | 1.0 | No |
|
||||
| <a id="opt-tracing-capturedRequestHeaders" href="#opt-tracing-capturedRequestHeaders" title="#opt-tracing-capturedRequestHeaders">`tracing.capturedRequestHeaders`</a> | Defines the list of request headers to add as attributes.<br />It applies to client and server kind spans. | [] | No |
|
||||
| <a id="opt-tracing-capturedResponseHeaders" href="#opt-tracing-capturedResponseHeaders" title="#opt-tracing-capturedResponseHeaders">`tracing.capturedResponseHeaders`</a> | Defines the list of response headers to add as attributes.<br />It applies to client and server kind spans. | [] | False |
|
||||
| <a id="opt-tracing-safeQueryParams" href="#opt-tracing-safeQueryParams" title="#opt-tracing-safeQueryParams">`tracing.safeQueryParams`</a> | By default, all query parameters are redacted.<br />Defines the list of query parameters to not redact. | [] | No |
|
||||
|
|
@ -61,6 +61,17 @@ tracing: {}
|
|||
| <a id="opt-tracing-otlp-grpc-tls-key" href="#opt-tracing-otlp-grpc-tls-key" title="#opt-tracing-otlp-grpc-tls-key">`tracing.otlp.grpc.tls.key`</a> | This instructs the exporter to send the tracing to the OpenTelemetry Collector using HTTP.<br /> Setting the sub-options with their default values. | ""null/false "" | No |
|
||||
| <a id="opt-tracing-otlp-grpc-tls-insecureskipverify" href="#opt-tracing-otlp-grpc-tls-insecureskipverify" title="#opt-tracing-otlp-grpc-tls-insecureskipverify">`tracing.otlp.grpc.tls.insecureskipverify`</a> | If `insecureSkipVerify` is `true`, the TLS connection to the OpenTelemetry Collector accepts any certificate presented by the server regardless of the hostnames it covers. | false | Yes |
|
||||
|
||||
## sampleRate
|
||||
|
||||
The `sampleRate` option controls trace sampling using a `ParentBased(TraceIDRatioBased)` strategy.
|
||||
|
||||
!!! info "Sampling Strategy Behavior"
|
||||
|
||||
- **Root spans** (trace originating at Traefik): Sampled according to the configured `sampleRate` using trace ID ratio-based sampling.
|
||||
- **Child spans** (requests with existing trace context): Inherit the sampling decision from the parent span, regardless of the local `sampleRate`.
|
||||
|
||||
This ensures consistent sampling decisions across distributed traces: once a trace is sampled, all spans in that trace are sampled, providing complete end-to-end visibility.
|
||||
|
||||
## resourceAttributes
|
||||
|
||||
The `resourceAttributes` option allows setting the resource attributes sent along the traces.
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ http:
|
|||
- "503"
|
||||
- "505-599"
|
||||
statusRewrites:
|
||||
"418": "404"
|
||||
"502-504": "500"
|
||||
"418": 404
|
||||
"502-504": 500
|
||||
service: error-handler-service
|
||||
query: "/{status}.html"
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,20 @@ tls:
|
|||
It is the only available method to configure the certificates (as well as the options and the stores).
|
||||
However, in [Kubernetes](../../../install-configuration/providers/kubernetes/kubernetes-crd.md), the certificates can and must be provided by [secrets](https://kubernetes.io/docs/concepts/configuration/secret/).
|
||||
|
||||
#### Certificate selection (SNI)
|
||||
|
||||
Traefik selects the certificate to present during the TLS handshake, based on the Server Name Indication (SNI) sent by the client.
|
||||
|
||||
However, HTTP router rules (e.g., `Host()`) are evaluated after TLS has been established, so they do not influence certificate selection.
|
||||
|
||||
##### Strict SNI Checking
|
||||
|
||||
By default, if the client does not send SNI, or if no certificate matches the requested server name,
|
||||
Traefik falls back to the [default certificate](#default-certificate) from the TLS store (if configured).
|
||||
|
||||
To reject connections without SNI (or with an unknown server name) instead of falling back to the default certificate,
|
||||
enable `sniStrict` in [TLS Options](./tls-options.md#strict-sni-checking).
|
||||
|
||||
## Certificates Stores
|
||||
|
||||
In Traefik, certificates are grouped together in certificates stores.
|
||||
|
|
@ -82,6 +96,12 @@ tls:
|
|||
|
||||
The `stores` list will actually be ignored and automatically set to `["default"]`.
|
||||
|
||||
!!! tip "Per provider examples"
|
||||
|
||||
- [Docker: Enable TLS](../../../../expose/docker/basic.md#enable-tls)
|
||||
- [Swarm: Enable TLS](../../../../expose/swarm/basic.md#enable-tls)
|
||||
- [Kubernetes: Enable TLS](../../../../expose/kubernetes/basic.md#enable-tls)
|
||||
|
||||
### Default Certificate
|
||||
|
||||
Traefik can use a default certificate for connections without a SNI, or without a matching domain.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ description: 'Traefik Hub API Gateway - Learn how to configure the JWT Authentic
|
|||
This middleware is available exclusively in [Traefik Hub](https://traefik.io/traefik-hub/). Learn more about [Traefik Hub's advanced features](https://doc.traefik.io/traefik-hub/api-gateway/intro).
|
||||
|
||||
JSON Web Token (JWT) (defined in the [RFC 7519](https://tools.ietf.org/html/rfc7519)) allows
|
||||
Traefik Hub API Gateway to secure the API access using a token signed using either a private signing secret or a plublic/private key.
|
||||
Traefik Hub API Gateway to secure the API access using a token signed using either a private signing secret or a public/private key.
|
||||
|
||||
Traefik Hub API Gateway provides many kinds of sources to perform the token validation:
|
||||
|
||||
|
|
|
|||
6
go.mod
6
go.mod
|
|
@ -1,6 +1,6 @@
|
|||
module github.com/traefik/traefik/v3
|
||||
|
||||
go 1.24.0
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.6.0
|
||||
|
|
@ -217,7 +217,7 @@ require (
|
|||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-logr/zapr v1.3.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.2 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.1 // indirect
|
||||
|
|
@ -392,7 +392,7 @@ require (
|
|||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/arch v0.4.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20241210194714-1829a127f884 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/oauth2 v0.34.0 // indirect
|
||||
golang.org/x/term v0.39.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
|
|
|
|||
7
go.sum
7
go.sum
|
|
@ -464,8 +464,9 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
|||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.21.2 h1:AqQaNADVwq/VnkCmQg6ogE+M3FOsKTytwges0JdwVuA=
|
||||
github.com/go-openapi/jsonpointer v0.21.2/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
|
||||
|
|
@ -1524,8 +1525,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU=
|
||||
golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
|
|
|
|||
|
|
@ -398,8 +398,7 @@ func (l *ServersLoadBalancer) Merge(other *ServersLoadBalancer) bool {
|
|||
|
||||
// SetDefaults Default values for a ServersLoadBalancer.
|
||||
func (l *ServersLoadBalancer) SetDefaults() {
|
||||
defaultPassHostHeader := DefaultPassHostHeader
|
||||
l.PassHostHeader = &defaultPassHostHeader
|
||||
l.PassHostHeader = ptr.To(DefaultPassHostHeader)
|
||||
|
||||
l.Strategy = BalancerStrategyWRR
|
||||
l.ResponseForwarding = &ResponseForwarding{}
|
||||
|
|
@ -473,8 +472,7 @@ type ServerHealthCheck struct {
|
|||
|
||||
// SetDefaults Default values for a HealthCheck.
|
||||
func (h *ServerHealthCheck) SetDefaults() {
|
||||
fr := true
|
||||
h.FollowRedirects = &fr
|
||||
h.FollowRedirects = ptr.To(true)
|
||||
h.Mode = "http"
|
||||
h.Interval = DefaultHealthCheckInterval
|
||||
h.Timeout = DefaultHealthCheckTimeout
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
ptypes "github.com/traefik/paerser/types"
|
||||
otypes "github.com/traefik/traefik/v3/pkg/observability/types"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
// EntryPoint holds the entry point configuration.
|
||||
|
|
@ -76,8 +77,7 @@ type HTTPConfig struct {
|
|||
|
||||
// SetDefaults sets the default values.
|
||||
func (c *HTTPConfig) SetDefaults() {
|
||||
sanitizePath := true
|
||||
c.SanitizePath = &sanitizePath
|
||||
c.SanitizePath = ptr.To(true)
|
||||
c.MaxHeaderBytes = http.DefaultMaxHeaderBytes
|
||||
}
|
||||
|
||||
|
|
@ -201,9 +201,8 @@ type ObservabilityConfig struct {
|
|||
|
||||
// SetDefaults sets the default values.
|
||||
func (o *ObservabilityConfig) SetDefaults() {
|
||||
defaultValue := true
|
||||
o.AccessLogs = &defaultValue
|
||||
o.Metrics = &defaultValue
|
||||
o.Tracing = &defaultValue
|
||||
o.AccessLogs = ptr.To(true)
|
||||
o.Metrics = ptr.To(true)
|
||||
o.Tracing = ptr.To(true)
|
||||
o.TraceVerbosity = otypes.MinimalVerbosity
|
||||
}
|
||||
|
|
|
|||
|
|
@ -571,12 +571,9 @@ func TestServiceTCPHealthChecker_differentIntervals(t *testing.T) {
|
|||
hc := NewServiceTCPHealthChecker(ctx, config, lb, serviceInfo, targets, "test-service")
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
wg.Go(func() {
|
||||
hc.Launch(ctx)
|
||||
wg.Done()
|
||||
}()
|
||||
})
|
||||
|
||||
// Let it run for 2 seconds to see the different check frequencies
|
||||
select {
|
||||
|
|
|
|||
|
|
@ -439,12 +439,9 @@ func TestServiceHealthChecker_Launch(t *testing.T) {
|
|||
hc := NewServiceHealthChecker(ctx, &MetricsMock{gauge}, config, lb, serviceInfo, http.DefaultTransport, map[string]*url.URL{"test": targetURL}, "foobar")
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
wg.Go(func() {
|
||||
hc.Launch(ctx)
|
||||
wg.Done()
|
||||
}()
|
||||
})
|
||||
|
||||
// Wait for expected health check events using channel synchronization.
|
||||
for i := range expectedEvents {
|
||||
|
|
@ -508,12 +505,10 @@ func TestDifferentIntervals(t *testing.T) {
|
|||
hc := NewServiceHealthChecker(ctx, &MetricsMock{gauge}, config, lb, serviceInfo, http.DefaultTransport, map[string]*url.URL{"healthy": healthyURL, "unhealthy": unhealthyURL}, "foobar")
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
wg.Go(func() {
|
||||
hc.Launch(ctx)
|
||||
wg.Done()
|
||||
}()
|
||||
})
|
||||
|
||||
select {
|
||||
case <-time.After(2 * time.Second):
|
||||
|
|
|
|||
|
|
@ -159,13 +159,11 @@ func NewHandler(ctx context.Context, config *otypes.AccessLog) (*Handler, error)
|
|||
}
|
||||
|
||||
if config.BufferingSize > 0 {
|
||||
logHandler.wg.Add(1)
|
||||
go func() {
|
||||
defer logHandler.wg.Done()
|
||||
logHandler.wg.Go(func() {
|
||||
for handlerParams := range logHandler.logHandlerChan {
|
||||
logHandler.logTheRoundTrip(handlerParams.ctx, handlerParams.logDataTable)
|
||||
}
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
return logHandler, nil
|
||||
|
|
|
|||
|
|
@ -98,16 +98,14 @@ func isWebsocketRequest(req *http.Request) bool {
|
|||
containsHeader := func(name, value string) bool {
|
||||
h := unsafeHeader(req.Header).Get(name)
|
||||
for {
|
||||
pos := strings.Index(h, ",")
|
||||
if pos == -1 {
|
||||
return strings.EqualFold(value, strings.TrimSpace(h))
|
||||
}
|
||||
|
||||
if strings.EqualFold(value, strings.TrimSpace(h[:pos])) {
|
||||
before, after, found := strings.Cut(h, ",")
|
||||
if strings.EqualFold(value, strings.TrimSpace(before)) {
|
||||
return true
|
||||
}
|
||||
|
||||
h = h[pos+1:]
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
h = after
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ func (c *OTelTracing) Setup(ctx context.Context, serviceName string, sampleRate
|
|||
// span processor to aggregate spans before export.
|
||||
bsp := sdktrace.NewBatchSpanProcessor(exporter)
|
||||
tracerProvider := sdktrace.NewTracerProvider(
|
||||
sdktrace.WithSampler(sdktrace.TraceIDRatioBased(sampleRate)),
|
||||
sdktrace.WithSampler(sdktrace.ParentBased(sdktrace.TraceIDRatioBased(sampleRate))),
|
||||
sdktrace.WithResource(res),
|
||||
sdktrace.WithSpanProcessor(bsp),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -147,16 +147,12 @@ func (eps TCPEntryPoints) Stop() {
|
|||
var wg sync.WaitGroup
|
||||
|
||||
for epn, ep := range eps {
|
||||
wg.Add(1)
|
||||
|
||||
go func(entryPointName string, entryPoint *TCPEntryPoint) {
|
||||
defer wg.Done()
|
||||
|
||||
logger := log.With().Str(logs.EntryPointName, entryPointName).Logger()
|
||||
entryPoint.Shutdown(logger.WithContext(context.Background()))
|
||||
wg.Go(func() {
|
||||
logger := log.With().Str(logs.EntryPointName, epn).Logger()
|
||||
ep.Shutdown(logger.WithContext(context.Background()))
|
||||
|
||||
logger.Debug().Msg("Entrypoint closed")
|
||||
}(epn, ep)
|
||||
})
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
|
@ -313,7 +309,6 @@ func (e *TCPEntryPoint) Shutdown(ctx context.Context) {
|
|||
var wg sync.WaitGroup
|
||||
|
||||
shutdownServer := func(server stoppable) {
|
||||
defer wg.Done()
|
||||
err := server.Shutdown(ctx)
|
||||
if err == nil {
|
||||
return
|
||||
|
|
@ -334,24 +329,19 @@ func (e *TCPEntryPoint) Shutdown(ctx context.Context) {
|
|||
}
|
||||
|
||||
if e.httpServer.Server != nil {
|
||||
wg.Add(1)
|
||||
go shutdownServer(e.httpServer.Server)
|
||||
wg.Go(func() { shutdownServer(e.httpServer.Server) })
|
||||
}
|
||||
|
||||
if e.httpsServer.Server != nil {
|
||||
wg.Add(1)
|
||||
go shutdownServer(e.httpsServer.Server)
|
||||
wg.Go(func() { shutdownServer(e.httpsServer.Server) })
|
||||
|
||||
if e.http3Server != nil {
|
||||
wg.Add(1)
|
||||
go shutdownServer(e.http3Server)
|
||||
wg.Go(func() { shutdownServer(e.http3Server) })
|
||||
}
|
||||
}
|
||||
|
||||
if e.tracker != nil {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
wg.Go(func() {
|
||||
err := e.tracker.Shutdown(ctx)
|
||||
if err == nil {
|
||||
return
|
||||
|
|
@ -360,7 +350,7 @@ func (e *TCPEntryPoint) Shutdown(ctx context.Context) {
|
|||
logger.Debug().Err(err).Msg("Server failed to shutdown before deadline")
|
||||
}
|
||||
e.tracker.Close()
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
|
|
|||
|
|
@ -50,16 +50,14 @@ func (eps UDPEntryPoints) Stop() {
|
|||
var wg sync.WaitGroup
|
||||
|
||||
for epn, ep := range eps {
|
||||
wg.Add(1)
|
||||
|
||||
go func(entryPointName string, entryPoint *UDPEntryPoint) {
|
||||
wg.Go(func() {
|
||||
defer wg.Done()
|
||||
|
||||
logger := log.With().Str(logs.EntryPointName, entryPointName).Logger()
|
||||
entryPoint.Shutdown(logger.WithContext(context.Background()))
|
||||
logger := log.With().Str(logs.EntryPointName, epn).Logger()
|
||||
ep.Shutdown(logger.WithContext(context.Background()))
|
||||
|
||||
logger.Debug().Msg("Entry point closed")
|
||||
}(epn, ep)
|
||||
})
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
|
|
|||
|
|
@ -592,9 +592,7 @@ func TestConcurrentInflightTracking(t *testing.T) {
|
|||
numRequests := 50
|
||||
|
||||
for range numRequests {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
wg.Go(func() {
|
||||
handler.inflightCount.Add(1)
|
||||
defer handler.inflightCount.Add(-1)
|
||||
|
||||
|
|
@ -608,7 +606,7 @@ func TestConcurrentInflightTracking(t *testing.T) {
|
|||
}
|
||||
|
||||
time.Sleep(1 * time.Millisecond)
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
|
@ -661,12 +659,10 @@ func TestConcurrentRequestsRespectInflight(t *testing.T) {
|
|||
inflightRequests := 5
|
||||
|
||||
for range inflightRequests {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
wg.Go(func() {
|
||||
recorder := httptest.NewRecorder()
|
||||
balancer.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
// Wait for goroutines to start and increment inflight counters.
|
||||
|
|
@ -687,9 +683,7 @@ func TestConcurrentRequestsRespectInflight(t *testing.T) {
|
|||
// Launch new requests in background so they don't block.
|
||||
var newWg sync.WaitGroup
|
||||
for range newRequests {
|
||||
newWg.Add(1)
|
||||
go func() {
|
||||
defer newWg.Done()
|
||||
newWg.Go(func() {
|
||||
rec := httptest.NewRecorder()
|
||||
balancer.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
server := rec.Header().Get("server")
|
||||
|
|
@ -698,7 +692,7 @@ func TestConcurrentRequestsRespectInflight(t *testing.T) {
|
|||
save[server]++
|
||||
saveMu.Unlock()
|
||||
}
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
// Wait for new requests to start and see the inflight counts.
|
||||
|
|
|
|||
Loading…
Reference in a new issue