@@ -30,64 +30,87 @@ import (
3030
3131var 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.
5577func 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)
7396func 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