Repository: istio/istio
File: pilot/pkg/networking/core/route/route.go (Go)

Code before:
	}

	// If there is only one destination cluster in route, return host:port/uri as description of route.
	// Otherwise there are multiple destination clusters and destination host is not clear. For that case
	// return virtual service name:port/uri as substitute.
	if c := in.GetRoute().GetCluster(); model.IsValidSubsetKey(c) {
		// Parse host and port from cluster name.
		_, _, h, p := model.ParseSubsetKey(c)
		return string(h) + ":" + strconv.Itoa(p) + path
	}
	return vsName + ":" + strconv.Itoa(port) + path
}

// BuildDefaultHTTPInboundRoute builds a default inbound route.
func BuildDefaultHTTPInboundRoute(clusterName string, operation string) *route.Route {
	out := buildDefaultHTTPRoute(clusterName, operation)
	// For inbound, configure with notimeout.
	out.GetRoute().Timeout = Notimeout
	out.GetRoute().MaxStreamDuration = &route.RouteAction_MaxStreamDuration{
		MaxStreamDuration: Notimeout,
		// If not configured at all, the grpc-timeout header is not used and
		// gRPC requests time out like any other requests using timeout or its default.
		GrpcTimeoutHeaderMax: Notimeout,
	}
	out.GetRoute().RetryPolicy = &route.RetryPolicy{
		RetryOn: "connect-failure,reset-before-request",
		NumRetries: &wrapperspb.UInt32Value{
			Value: 2,
		},
	}
	return out
}

func buildDefaultHTTPRoute(clusterName string, operation string) *route.Route {
	routeAction := &route.RouteAction{
		ClusterSpecifier: &route.RouteAction_Cluster{Cluster: clusterName},
	}
	val := &route.Route{
		Match: TranslateRouteMatch(config.Config{}, nil, true),
		Decorator: &route.Decorator{
			Operation: operation,
		},
		Action: &route.Route_Route{
			Route: routeAction,
		},
	}

	val.Name = DefaultRouteName
	return val
}


Review comment (bug):
About `connect-failure`, without setting inbound, it has already been covered with default outbound retry policy.

About `reset-before-request`, inbound retry on it can supplement cases where request has been sent to uypstream envoy, but envoy has not chance to send to server instance. 

So reset-before-request seems meaningful

Code after:
	}

	// If there is only one destination cluster in route, return host:port/uri as description of route.
	// Otherwise there are multiple destination clusters and destination host is not clear. For that case
	// return virtual service name:port/uri as substitute.
	if c := in.GetRoute().GetCluster(); model.IsValidSubsetKey(c) {
		// Parse host and port from cluster name.
		_, _, h, p := model.ParseSubsetKey(c)
		return string(h) + ":" + strconv.Itoa(p) + path
	}
	return vsName + ":" + strconv.Itoa(port) + path
}

// BuildDefaultHTTPInboundRoute builds a default inbound route.
func BuildDefaultHTTPInboundRoute(proxy *model.Proxy, clusterName string, operation string) *route.Route {
	out := buildDefaultHTTPRoute(clusterName, operation)
	// For inbound, configure with notimeout.
	out.GetRoute().Timeout = Notimeout
	out.GetRoute().MaxStreamDuration = &route.RouteAction_MaxStreamDuration{
		MaxStreamDuration: Notimeout,
		// If not configured at all, the grpc-timeout header is not used and
		// gRPC requests time out like any other requests using timeout or its default.
		GrpcTimeoutHeaderMax: Notimeout,
	}
	if util.VersionGreaterOrEqual124(proxy) && features.EnableInboundRetryPolicy {
		out.GetRoute().RetryPolicy = &route.RetryPolicy{
			RetryOn: "reset-before-request",
			NumRetries: &wrapperspb.UInt32Value{
				Value: 2,
			},
		}
	}
	return out
}

func buildDefaultHTTPRoute(clusterName string, operation string) *route.Route {
	routeAction := &route.RouteAction{
		ClusterSpecifier: &route.RouteAction_Cluster{Cluster: clusterName},
	}
	val := &route.Route{
		Match: TranslateRouteMatch(config.Config{}, nil, true),
		Decorator: &route.Decorator{
			Operation: operation,
		},
		Action: &route.Route_Route{
			Route: routeAction,
		},
	}

	val.Name = DefaultRouteName
	return val