Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions internal/xds/translator/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func buildXdsRoute(httpRoute *ir.HTTPRoute, httpListener *ir.HTTPListener) (*rou
router.Action = &routev3.Route_Redirect{Redirect: buildXdsRedirectAction(httpRoute)}
case httpRoute.URLRewrite != nil:
routeAction := buildXdsURLRewriteAction(httpRoute, httpRoute.URLRewrite, httpRoute.PathMatch)
routeAction.IdleTimeout = idleTimeout(httpRoute)
routeAction.IdleTimeout = idleTimeout(httpRoute, httpListener)
if httpRoute.Mirrors != nil {
routeAction.RequestMirrorPolicies = buildXdsRequestMirrorPolicies(httpRoute.Mirrors)
}
Expand All @@ -86,7 +86,7 @@ func buildXdsRoute(httpRoute *ir.HTTPRoute, httpListener *ir.HTTPListener) (*rou
router.Action = &routev3.Route_Route{Route: routeAction}
default:
routeAction := buildXdsRouteAction(httpRoute)
routeAction.IdleTimeout = idleTimeout(httpRoute)
routeAction.IdleTimeout = idleTimeout(httpRoute, httpListener)

if httpRoute.Mirrors != nil {
routeAction.RequestMirrorPolicies = buildXdsRequestMirrorPolicies(httpRoute.Mirrors)
Expand Down Expand Up @@ -408,21 +408,31 @@ func getEffectiveRequestTimeout(httpRoute *ir.HTTPRoute) *metav1.Duration {
return nil
}

func idleTimeout(httpRoute *ir.HTTPRoute) *durationpb.Duration {
rt := getEffectiveRequestTimeout(httpRoute)
timeout := time.Hour // Default to 1 hour
if rt != nil {
// Ensure is not less than the request timeout
if timeout < rt.Duration {
timeout = rt.Duration
}
func idleTimeout(httpRoute *ir.HTTPRoute, httpListener *ir.HTTPListener) *durationpb.Duration {
// When a user-configured stream idle timeout exists at the listener level, avoid overriding it at the route level
// and allow the user-configured listener-level timeout to take effect.
// TODO: we may need to support route-level idle timeout in the BackendTrafficPolicy
if httpListener != nil &&
httpListener.Timeout != nil &&
httpListener.Timeout.HTTP != nil &&
httpListener.Timeout.HTTP.StreamIdleTimeout != nil {
return nil
}

// When a user-configured request timeout exists at the route level, and no user-configured stream idle timeout exists
// at the listener level, set a route-level idle timeout to avoid stream timeout before request timeout.
requestTimeout := getEffectiveRequestTimeout(httpRoute)
idleTimeout := time.Hour // Default to 1 hour
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we could remove the route-level implicit default, and add a warning status to the HTTPRoute when the configured request timeout is longer than the default HCM-level 5 minutes idle timeout - this would be a breaking change.

if requestTimeout != nil {
// Ensure the idle timeout is not less than the request timeout
if idleTimeout < requestTimeout.Duration {
idleTimeout = requestTimeout.Duration
}
// Disable idle timeout when request timeout is disabled
if rt.Duration == 0 {
timeout = 0
if requestTimeout.Duration == 0 {
idleTimeout = 0
}

return durationpb.New(timeout)
return durationpb.New(idleTimeout)
}
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,32 @@ http:
- host: "1.2.3.4"
port: 50002
name: "seventh-route-dest/backend/0"
- name: "second-listener"
address: "::"
port: 10081
hostnames:
- "*"
path:
mergeSlashes: true
escapedSlashesAction: UnescapeAndRedirect
timeout:
http:
streamIdleTimeout: 10s
routes:
- name: "first-route"
hostname: "*"
traffic:
timeout:
http:
requestTimeout: 5s # should not set route-level idle timeout because listener has it
headerMatches:
- name: user
stringMatch:
exact: "jason"
destination:
name: "first-route-dest"
settings:
- endpoints:
- host: "1.2.3.4"
port: 50000
name: "first-route-dest/backend/0"
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,39 @@
maxConnectionsToAcceptPerSocketEvent: 1
name: first-listener
perConnectionBufferLimitBytes: 32768
- address:
socketAddress:
address: '::'
portValue: 10081
defaultFilterChain:
filters:
- name: envoy.filters.network.http_connection_manager
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
commonHttpProtocolOptions:
headersWithUnderscoresAction: REJECT_REQUEST
http2ProtocolOptions:
initialConnectionWindowSize: 1048576
initialStreamWindowSize: 65536
maxConcurrentStreams: 100
httpFilters:
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
suppressEnvoyHeaders: true
mergeSlashes: true
normalizePath: true
pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
rds:
configSource:
ads: {}
resourceApiVersion: V3
routeConfigName: second-listener
serverHeaderTransformation: PASS_THROUGH
statPrefix: http-10081
streamIdleTimeout: 10s
useRemoteAddress: true
name: second-listener
maxConnectionsToAcceptPerSocketEvent: 1
name: second-listener
perConnectionBufferLimitBytes: 32768
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,22 @@
timeout: 0s
upgradeConfigs:
- upgradeType: websocket
- ignorePortInHostMatching: true
name: second-listener
virtualHosts:
- domains:
- '*'
name: second-listener/*
routes:
- match:
headers:
- name: user
stringMatch:
exact: jason
prefix: /
name: first-route
route:
cluster: first-route-dest
timeout: 5s
upgradeConfigs:
- upgradeType: websocket