Skip to content

Commit

Permalink
do not add previous hosts predicate when consistent hashing is enabled (
Browse files Browse the repository at this point in the history
#50759)

Signed-off-by: Rama Chavali <[email protected]>
  • Loading branch information
ramaraochavali committed May 14, 2024
1 parent 421d3f7 commit 3727b57
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 19 deletions.
2 changes: 1 addition & 1 deletion pilot/pkg/networking/core/listener_waypoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ func (lb *ListenerBuilder) routeDestination(out *route.Route, in *networking.HTT
policy = lb.push.Mesh.GetDefaultHttpRetryPolicy()
}
action := &route.RouteAction{
RetryPolicy: retry.ConvertPolicy(policy),
RetryPolicy: retry.ConvertPolicy(policy, false),
}

// Configure timeouts specified by Virtual Service if they are provided, otherwise set it to defaults.
Expand Down
32 changes: 24 additions & 8 deletions pilot/pkg/networking/core/route/retry/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,32 @@ var defaultRetryPriorityTypedConfig = protoconv.MessageToAny(buildPreviousPriori

// DefaultPolicy gets a copy of the default retry policy.
func DefaultPolicy() *route.RetryPolicy {
policy := defaultPolicy()
policy.RetryHostPredicate = []*route.RetryPolicy_RetryHostPredicate{
// to configure retries to prefer hosts that haven’t been attempted already,
// the builtin `envoy.retry_host_predicates.previous_hosts` predicate can be used.
xdsfilters.RetryPreviousHosts,
}
return policy
}

func defaultPolicy() *route.RetryPolicy {
policy := route.RetryPolicy{
NumRetries: &wrappers.UInt32Value{Value: 2},
RetryOn: "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes",
RetriableStatusCodes: []uint32{http.StatusServiceUnavailable},
RetryHostPredicate: []*route.RetryPolicy_RetryHostPredicate{
// to configure retries to prefer hosts that haven’t been attempted already,
// the builtin `envoy.retry_host_predicates.previous_hosts` predicate can be used.
xdsfilters.RetryPreviousHosts,
},
// TODO: allow this to be configured via API.
HostSelectionRetryMaxAttempts: 5,
}
return &policy
}

// DefaultConsistentHashPolicy gets a copy of the default retry policy without previous host predicate.
// When Consistent Hashing is enabled, we don't want to use other hosts during retries.
func DefaultConsistentHashPolicy() *route.RetryPolicy {
return defaultPolicy()
}

// ConvertPolicy converts the given Istio retry policy to an Envoy policy.
//
// If in is nil, DefaultPolicy is returned.
Expand All @@ -61,10 +72,16 @@ func DefaultPolicy() *route.RetryPolicy {
// is appended when encountering parts that are valid HTTP status codes.
//
// - PerTryTimeout: set from in.PerTryTimeout (if specified)
func ConvertPolicy(in *networking.HTTPRetry) *route.RetryPolicy {
func ConvertPolicy(in *networking.HTTPRetry, hashPolicy bool) *route.RetryPolicy {
var out *route.RetryPolicy
if hashPolicy {
out = DefaultConsistentHashPolicy()
} else {
out = DefaultPolicy()
}
if in == nil {
// No policy was set, use a default.
return DefaultPolicy()
return out
}

if in.Attempts <= 0 {
Expand All @@ -73,7 +90,6 @@ func ConvertPolicy(in *networking.HTTPRetry) *route.RetryPolicy {
}

// A policy was specified. Start with the default and override with user-provided fields where appropriate.
out := DefaultPolicy()
out.NumRetries = &wrappers.UInt32Value{Value: uint32(in.Attempts)}

if in.RetryOn != "" {
Expand Down
2 changes: 1 addition & 1 deletion pilot/pkg/networking/core/route/retry/retry_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func TestRetry(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
g := NewWithT(t)
policy := retry.ConvertPolicy(tc.route.Retries)
policy := retry.ConvertPolicy(tc.route.Retries, false)
if tc.assertFunc != nil {
tc.assertFunc(g, policy)
}
Expand Down
20 changes: 11 additions & 9 deletions pilot/pkg/networking/core/route/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,14 +553,7 @@ func applyHTTPRouteDestination(
listenerPort int,
hashByDestination DestinationHashMap,
) []host.Name {
policy := in.Retries
if policy == nil {
// No VS policy set, use mesh defaults
policy = mesh.GetDefaultHttpRetryPolicy()
}
action := &route.RouteAction{
RetryPolicy: retry.ConvertPolicy(policy),
}
action := &route.RouteAction{}

setTimeout(action, in.Timeout, node)

Expand Down Expand Up @@ -622,8 +615,16 @@ func applyHTTPRouteDestination(
}

var hostnames []host.Name
policy := in.Retries
if policy == nil {
// No VS policy set, use mesh defaults
policy = mesh.GetDefaultHttpRetryPolicy()
}
consistentHash := false
if len(in.Route) == 1 {
hostnames = append(hostnames, processDestination(in.Route[0], serviceRegistry, listenerPort, hashByDestination, out, action))
hash := hashByDestination[in.Route[0]]
consistentHash = hash != nil
} else {
weighted := make([]*route.WeightedCluster_ClusterWeight, 0)
for _, dst := range in.Route {
Expand All @@ -641,6 +642,7 @@ func applyHTTPRouteDestination(
},
}
}
action.RetryPolicy = retry.ConvertPolicy(policy, consistentHash)
return hostnames
}

Expand Down Expand Up @@ -1290,7 +1292,7 @@ func setTimeout(action *route.RouteAction, vsTimeout *durationpb.Duration, node
func BuildDefaultHTTPOutboundRoute(clusterName string, operation string, mesh *meshconfig.MeshConfig) *route.Route {
out := buildDefaultHTTPRoute(clusterName, operation)
// Add a default retry policy for outbound routes.
out.GetRoute().RetryPolicy = retry.ConvertPolicy(mesh.GetDefaultHttpRetryPolicy())
out.GetRoute().RetryPolicy = retry.ConvertPolicy(mesh.GetDefaultHttpRetryPolicy(), false)
setTimeout(out.GetRoute(), nil, nil)
return out
}
Expand Down
3 changes: 3 additions & 0 deletions pilot/pkg/networking/core/route/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ func TestBuildHTTPRoutes(t *testing.T) {
g.Expect(routes[1].StatPrefix).To(Equal(""))
g.Expect(routes[2].GetMatch().GetPrefix()).To(Equal("/bar"))
g.Expect(routes[2].StatPrefix).To(Equal(""))
g.Expect(len(routes[0].GetRoute().GetRetryPolicy().RetryHostPredicate)).To(Equal(1))
})

t.Run("for virtual service with exact matching on JWT claims", func(t *testing.T) {
Expand Down Expand Up @@ -513,6 +514,7 @@ func TestBuildHTTPRoutes(t *testing.T) {
},
}
g.Expect(routes[0].GetRoute().GetHashPolicy()).To(ConsistOf(hashPolicy))
g.Expect(len(routes[0].GetRoute().GetRetryPolicy().RetryHostPredicate)).To(Equal(0))
})

t.Run("for virtual service with query param based ring hash", func(t *testing.T) {
Expand Down Expand Up @@ -560,6 +562,7 @@ func TestBuildHTTPRoutes(t *testing.T) {
},
}
g.Expect(routes[0].GetRoute().GetHashPolicy()).To(ConsistOf(hashPolicy))
g.Expect(len(routes[0].GetRoute().GetRetryPolicy().RetryHostPredicate)).To(Equal(0))
})

t.Run("for virtual service with subsets with ring hash", func(t *testing.T) {
Expand Down

0 comments on commit 3727b57

Please sign in to comment.