Skip to content

Commit bb1b3c2

Browse files
cache default retry policy (#58515)
Signed-off-by: Rama Chavali <rama.rao@salesforce.com>
1 parent 1441efa commit bb1b3c2

File tree

1 file changed

+62
-48
lines changed
  • pilot/pkg/networking/core/route/retry

1 file changed

+62
-48
lines changed

pilot/pkg/networking/core/route/retry/retry.go

Lines changed: 62 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -30,64 +30,87 @@ import (
3030

3131
var defaultRetryPriorityTypedConfig = protoconv.MessageToAny(buildPreviousPrioritiesConfig())
3232

33-
// DefaultPolicy gets a copy of the default retry policy.
34-
func DefaultPolicy() *route.RetryPolicy {
35-
policy := defaultPolicy()
36-
policy.RetryHostPredicate = []*route.RetryPolicy_RetryHostPredicate{
37-
// to configure retries to prefer hosts that haven’t been attempted already,
38-
// the builtin `envoy.retry_host_predicates.previous_hosts` predicate can be used.
33+
// Cached immutable default values to avoid repeated allocations.
34+
// These are shared and must not be modified.
35+
var (
36+
defaultNumRetries = &wrappers.UInt32Value{Value: 2}
37+
defaultRetryOn = "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes"
38+
39+
// Shared slice for RetryHostPredicate - immutable, safe to share
40+
defaultRetryHostPredicate = []*route.RetryPolicy_RetryHostPredicate{
3941
xdsfilters.RetryPreviousHosts,
4042
}
41-
return policy
42-
}
4343

44-
func defaultPolicy() *route.RetryPolicy {
45-
return &route.RetryPolicy{
46-
NumRetries: &wrappers.UInt32Value{Value: 2},
47-
RetryOn: "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
48-
// TODO: allow this to be configured via API.
44+
// Cached default policy with RetryHostPredicate (for non-consistent-hash cases)
45+
cachedDefaultPolicy = &route.RetryPolicy{
46+
NumRetries: defaultNumRetries,
47+
RetryOn: defaultRetryOn,
4948
HostSelectionRetryMaxAttempts: 5,
49+
RetryHostPredicate: defaultRetryHostPredicate,
50+
}
51+
52+
// Cached default policy without RetryHostPredicate (for consistent-hash cases)
53+
cachedDefaultConsistentHashPolicy = &route.RetryPolicy{
54+
NumRetries: defaultNumRetries,
55+
RetryOn: defaultRetryOn,
56+
HostSelectionRetryMaxAttempts: 5,
57+
}
58+
59+
cachedRetryRemoteLocalitiesPredicate = &route.RetryPolicy_RetryPriority{
60+
Name: "envoy.retry_priorities.previous_priorities",
61+
ConfigType: &route.RetryPolicy_RetryPriority_TypedConfig{
62+
TypedConfig: defaultRetryPriorityTypedConfig,
63+
},
5064
}
65+
)
66+
67+
// DefaultPolicy returns the default retry policy.
68+
// The returned policy is a shared immutable instance and must not be modified.
69+
// If modification is needed, use newRetryPolicy() instead.
70+
func DefaultPolicy() *route.RetryPolicy {
71+
return cachedDefaultPolicy
5172
}
5273

53-
// DefaultConsistentHashPolicy gets a copy of the default retry policy without previous host predicate.
74+
// DefaultConsistentHashPolicy returns the default retry policy without previous host predicate.
5475
// When Consistent Hashing is enabled, we don't want to use other hosts during retries.
76+
// The returned policy is a shared immutable instance and must not be modified.
5577
func DefaultConsistentHashPolicy() *route.RetryPolicy {
56-
return defaultPolicy()
78+
return cachedDefaultConsistentHashPolicy
79+
}
80+
81+
// newRetryPolicy creates a new mutable retry policy with default values.
82+
// Use this when the policy needs to be customized.
83+
func newRetryPolicy(hashPolicy bool) *route.RetryPolicy {
84+
policy := &route.RetryPolicy{
85+
NumRetries: &wrappers.UInt32Value{Value: 2},
86+
RetryOn: defaultRetryOn,
87+
HostSelectionRetryMaxAttempts: 5,
88+
}
89+
if !hashPolicy {
90+
policy.RetryHostPredicate = defaultRetryHostPredicate
91+
}
92+
return policy
5793
}
5894

5995
// ConvertPolicy converts the given Istio retry policy to an Envoy policy.
60-
//
61-
// If in is nil, DefaultPolicy is returned.
62-
//
63-
// If in.Attempts == 0, returns nil.
64-
//
65-
// Otherwise, the returned policy is DefaultPolicy with the following overrides:
66-
//
67-
// - NumRetries: set from in.Attempts
68-
//
69-
// - RetryOn, RetriableStatusCodes: set from in.RetryOn (if specified). RetriableStatusCodes
70-
// is appended when encountering parts that are valid HTTP status codes.
71-
//
72-
// - PerTryTimeout: set from in.PerTryTimeout (if specified)
7396
func ConvertPolicy(in *networking.HTTPRetry, hashPolicy bool) *route.RetryPolicy {
74-
var out *route.RetryPolicy
75-
if hashPolicy {
76-
out = DefaultConsistentHashPolicy()
77-
} else {
78-
out = DefaultPolicy()
79-
}
97+
// Fast path: if no custom config, return cached immutable default
8098
if in == nil {
81-
// No policy was set, use a default.
82-
return out
99+
if hashPolicy {
100+
return cachedDefaultConsistentHashPolicy
101+
}
102+
return cachedDefaultPolicy
83103
}
84104

85105
if in.Attempts <= 0 {
86106
// Configuration is explicitly disabling the retry policy.
87107
return nil
88108
}
89109

90-
// A policy was specified. Start with the default and override with user-provided fields where appropriate.
110+
// A policy was specified - we need a mutable copy to customize
111+
out := newRetryPolicy(hashPolicy)
112+
113+
// Override with user-provided fields
91114
out.NumRetries = &wrappers.UInt32Value{Value: uint32(in.Attempts)}
92115

93116
if in.RetryOn != "" {
@@ -108,22 +131,13 @@ func ConvertPolicy(in *networking.HTTPRetry, hashPolicy bool) *route.RetryPolicy
108131
if in.RetryIgnorePreviousHosts != nil {
109132
var retryHostPredicate []*route.RetryPolicy_RetryHostPredicate
110133
if in.RetryIgnorePreviousHosts.GetValue() {
111-
retryHostPredicate = []*route.RetryPolicy_RetryHostPredicate{
112-
// to configure retries to prefer hosts that haven’t been attempted already,
113-
// the builtin `envoy.retry_host_predicates.previous_hosts` predicate can be used.
114-
xdsfilters.RetryPreviousHosts,
115-
}
134+
retryHostPredicate = defaultRetryHostPredicate
116135
}
117136
out.RetryHostPredicate = retryHostPredicate
118137
}
119138

120139
if in.RetryRemoteLocalities != nil && in.RetryRemoteLocalities.GetValue() {
121-
out.RetryPriority = &route.RetryPolicy_RetryPriority{
122-
Name: "envoy.retry_priorities.previous_priorities",
123-
ConfigType: &route.RetryPolicy_RetryPriority_TypedConfig{
124-
TypedConfig: defaultRetryPriorityTypedConfig,
125-
},
126-
}
140+
out.RetryPriority = cachedRetryRemoteLocalitiesPredicate
127141
}
128142

129143
if in.Backoff != nil {

0 commit comments

Comments
 (0)