Skip to content

Commit 9d2b27d

Browse files
authored
feat: support stream idle timeout (#6481)
* feat: support stream idle timeout Signed-off-by: Muhammad Abduh <mabdh.mabdh@gmail.com>
1 parent 6b699c8 commit 9d2b27d

18 files changed

+451
-0
lines changed

api/v1alpha1/timeout_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,10 @@ type HTTPClientTimeout struct {
8181
//
8282
// +optional
8383
IdleTimeout *gwapiv1.Duration `json:"idleTimeout,omitempty"`
84+
85+
// The stream idle timeout defines the amount of time a stream can exist without any upstream or downstream activity.
86+
// Default: 5 minutes.
87+
//
88+
// +optional
89+
StreamIdleTimeout *gwapiv1.Duration `json:"streamIdleTimeout,omitempty"`
8490
}

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,12 @@ spec:
726726
initiation and stops when either the last byte of the request is sent upstream or when the response begins.
727727
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
728728
type: string
729+
streamIdleTimeout:
730+
description: |2-
731+
The stream idle timeout defines the amount of time a stream can exist without any upstream or downstream activity.
732+
Default: 5 minutes.
733+
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
734+
type: string
729735
type: object
730736
tcp:
731737
description: Timeout settings for TCP.

charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,6 +725,12 @@ spec:
725725
initiation and stops when either the last byte of the request is sent upstream or when the response begins.
726726
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
727727
type: string
728+
streamIdleTimeout:
729+
description: |2-
730+
The stream idle timeout defines the amount of time a stream can exist without any upstream or downstream activity.
731+
Default: 5 minutes.
732+
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
733+
type: string
728734
type: object
729735
tcp:
730736
description: Timeout settings for TCP.

internal/gatewayapi/clienttrafficpolicy.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,16 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout,
603603
Duration: d,
604604
}
605605
}
606+
607+
if clientTimeout.HTTP.StreamIdleTimeout != nil {
608+
d, err := time.ParseDuration(string(*clientTimeout.HTTP.StreamIdleTimeout))
609+
if err != nil {
610+
return nil, fmt.Errorf("invalid HTTP StreamIdleTimeout value %s", *clientTimeout.HTTP.StreamIdleTimeout)
611+
}
612+
irHTTPTimeout.StreamIdleTimeout = &metav1.Duration{
613+
Duration: d,
614+
}
615+
}
606616
irClientTimeout.HTTP = irHTTPTimeout
607617
}
608618

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
clientTrafficPolicies:
2+
- apiVersion: gateway.envoyproxy.io/v1alpha1
3+
kind: ClientTrafficPolicy
4+
metadata:
5+
namespace: envoy-gateway
6+
name: target-gateway
7+
spec:
8+
targetRef:
9+
group: gateway.networking.k8s.io
10+
kind: Gateway
11+
name: gateway
12+
sectionName: http-1
13+
timeout:
14+
http:
15+
requestReceivedTimeout: "5s"
16+
streamIdleTimeout: "1h"
17+
gateways:
18+
- apiVersion: gateway.networking.k8s.io/v1
19+
kind: Gateway
20+
metadata:
21+
namespace: envoy-gateway
22+
name: gateway
23+
spec:
24+
gatewayClassName: envoy-gateway-class
25+
listeners:
26+
- name: http-1
27+
protocol: HTTP
28+
port: 80
29+
allowedRoutes:
30+
namespaces:
31+
from: Same
32+
- name: http-2
33+
protocol: HTTP
34+
port: 8080
35+
allowedRoutes:
36+
namespaces:
37+
from: Same
38+
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
clientTrafficPolicies:
2+
- apiVersion: gateway.envoyproxy.io/v1alpha1
3+
kind: ClientTrafficPolicy
4+
metadata:
5+
creationTimestamp: null
6+
name: target-gateway
7+
namespace: envoy-gateway
8+
spec:
9+
targetRef:
10+
group: gateway.networking.k8s.io
11+
kind: Gateway
12+
name: gateway
13+
sectionName: http-1
14+
timeout:
15+
http:
16+
requestReceivedTimeout: 5s
17+
streamIdleTimeout: 1h
18+
status:
19+
ancestors:
20+
- ancestorRef:
21+
group: gateway.networking.k8s.io
22+
kind: Gateway
23+
name: gateway
24+
namespace: envoy-gateway
25+
sectionName: http-1
26+
conditions:
27+
- lastTransitionTime: null
28+
message: Policy has been accepted.
29+
reason: Accepted
30+
status: "True"
31+
type: Accepted
32+
controllerName: gateway.envoyproxy.io/gatewayclass-controller
33+
gateways:
34+
- apiVersion: gateway.networking.k8s.io/v1
35+
kind: Gateway
36+
metadata:
37+
creationTimestamp: null
38+
name: gateway
39+
namespace: envoy-gateway
40+
spec:
41+
gatewayClassName: envoy-gateway-class
42+
listeners:
43+
- allowedRoutes:
44+
namespaces:
45+
from: Same
46+
name: http-1
47+
port: 80
48+
protocol: HTTP
49+
- allowedRoutes:
50+
namespaces:
51+
from: Same
52+
name: http-2
53+
port: 8080
54+
protocol: HTTP
55+
status:
56+
listeners:
57+
- attachedRoutes: 0
58+
conditions:
59+
- lastTransitionTime: null
60+
message: Sending translated listener configuration to the data plane
61+
reason: Programmed
62+
status: "True"
63+
type: Programmed
64+
- lastTransitionTime: null
65+
message: Listener has been successfully translated
66+
reason: Accepted
67+
status: "True"
68+
type: Accepted
69+
- lastTransitionTime: null
70+
message: Listener references have been resolved
71+
reason: ResolvedRefs
72+
status: "True"
73+
type: ResolvedRefs
74+
name: http-1
75+
supportedKinds:
76+
- group: gateway.networking.k8s.io
77+
kind: HTTPRoute
78+
- group: gateway.networking.k8s.io
79+
kind: GRPCRoute
80+
- attachedRoutes: 0
81+
conditions:
82+
- lastTransitionTime: null
83+
message: Sending translated listener configuration to the data plane
84+
reason: Programmed
85+
status: "True"
86+
type: Programmed
87+
- lastTransitionTime: null
88+
message: Listener has been successfully translated
89+
reason: Accepted
90+
status: "True"
91+
type: Accepted
92+
- lastTransitionTime: null
93+
message: Listener references have been resolved
94+
reason: ResolvedRefs
95+
status: "True"
96+
type: ResolvedRefs
97+
name: http-2
98+
supportedKinds:
99+
- group: gateway.networking.k8s.io
100+
kind: HTTPRoute
101+
- group: gateway.networking.k8s.io
102+
kind: GRPCRoute
103+
infraIR:
104+
envoy-gateway/gateway:
105+
proxy:
106+
listeners:
107+
- address: null
108+
name: envoy-gateway/gateway/http-1
109+
ports:
110+
- containerPort: 10080
111+
name: http-80
112+
protocol: HTTP
113+
servicePort: 80
114+
- address: null
115+
name: envoy-gateway/gateway/http-2
116+
ports:
117+
- containerPort: 8080
118+
name: http-8080
119+
protocol: HTTP
120+
servicePort: 8080
121+
metadata:
122+
labels:
123+
gateway.envoyproxy.io/owning-gateway-name: gateway
124+
gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
125+
ownerReference:
126+
kind: GatewayClass
127+
name: envoy-gateway-class
128+
name: envoy-gateway/gateway
129+
namespace: envoy-gateway-system
130+
xdsIR:
131+
envoy-gateway/gateway:
132+
accessLog:
133+
json:
134+
- path: /dev/stdout
135+
http:
136+
- address: 0.0.0.0
137+
hostnames:
138+
- '*'
139+
isHTTP2: false
140+
metadata:
141+
kind: Gateway
142+
name: gateway
143+
namespace: envoy-gateway
144+
sectionName: http-1
145+
name: envoy-gateway/gateway/http-1
146+
path:
147+
escapedSlashesAction: UnescapeAndRedirect
148+
mergeSlashes: true
149+
port: 10080
150+
timeout:
151+
http:
152+
requestReceivedTimeout: 5s
153+
streamIdleTimeout: 1h0m0s
154+
- address: 0.0.0.0
155+
hostnames:
156+
- '*'
157+
isHTTP2: false
158+
metadata:
159+
kind: Gateway
160+
name: gateway
161+
namespace: envoy-gateway
162+
sectionName: http-2
163+
name: envoy-gateway/gateway/http-2
164+
path:
165+
escapedSlashesAction: UnescapeAndRedirect
166+
mergeSlashes: true
167+
port: 8080
168+
readyListener:
169+
address: 0.0.0.0
170+
ipFamily: IPv4
171+
path: /ready
172+
port: 19003

internal/ir/xds.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,12 @@ type HTTPClientTimeout struct {
740740
RequestReceivedTimeout *metav1.Duration `json:"requestReceivedTimeout,omitempty" yaml:"requestReceivedTimeout,omitempty"`
741741
// IdleTimeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
742742
IdleTimeout *metav1.Duration `json:"idleTimeout,omitempty" yaml:"idleTimeout,omitempty"`
743+
// The stream idle timeout for connections managed by the connection manager.
744+
// If not specified, this defaults to 5 minutes. The default value was selected
745+
// so as not to interfere with any smaller configured timeouts that may have
746+
// existed in configurations prior to the introduction of this feature, while
747+
// introducing robustness to TCP connections that terminate without a FIN.
748+
StreamIdleTimeout *metav1.Duration `json:"streamIdleTimeout,omitempty" yaml:"streamIdleTimeout,omitempty"`
743749
}
744750

745751
// HTTPRoute holds the route information associated with the HTTP Route

internal/ir/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/xds/translator/listener.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irLis
382382
if irListener.Timeout.HTTP.IdleTimeout != nil {
383383
mgr.CommonHttpProtocolOptions.IdleTimeout = durationpb.New(irListener.Timeout.HTTP.IdleTimeout.Duration)
384384
}
385+
386+
if irListener.Timeout.HTTP.StreamIdleTimeout != nil {
387+
mgr.StreamIdleTimeout = durationpb.New(irListener.Timeout.HTTP.StreamIdleTimeout.Duration)
388+
}
385389
}
386390

387391
// Add the proxy protocol filter if needed

0 commit comments

Comments
 (0)