Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

outbound: implement OutboundPolicy retries #2446

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7c8c734
proxy-api plumbing
hawkw Jul 25, 2023
600d8ab
BLBLBLBLBLBLGGHGHGHGH
hawkw Jul 25, 2023
86d618d
testy fixy
hawkw Jul 25, 2023
54adb08
generify
hawkw Jul 25, 2023
5efdbd0
more stuff
hawkw Jul 26, 2023
4dd80a3
wip
hawkw Jul 26, 2023
47249a5
plumbing (mostly) done
hawkw Jul 26, 2023
3043d96
okay now it's good
hawkw Jul 26, 2023
78a6420
okay cool it compiles for real now
hawkw Jul 26, 2023
faf4eda
add basic retry test
hawkw Jul 26, 2023
36ec704
fix wrong retry budget range minimum
hawkw Jul 26, 2023
64f5eec
more retry tests
hawkw Jul 26, 2023
18ac612
add post body tests
hawkw Jul 26, 2023
f43c88f
add tests for timeout interaction
hawkw Jul 26, 2023
95bc567
fix request timeout not actually getting hit in test
hawkw Jul 27, 2023
9a0cf7f
handle backend request timeouts as 504s
hawkw Jul 27, 2023
d9960c8
actually propagate `EmitHeaders` config
hawkw Jul 27, 2023
30a8ab4
self-review: undo unneeded diff
hawkw Jul 27, 2023
c31fc6d
self-review cleanup
hawkw Jul 27, 2023
a7fe063
move retry tests into their own module
hawkw Jul 27, 2023
7b1529a
document tests
hawkw Jul 27, 2023
528d143
fix missing client handles in tests
hawkw Jul 27, 2023
7a7b88c
fix backend timeout test
hawkw Jul 27, 2023
119a7fb
update lockfile
hawkw Aug 11, 2023
b363f14
move TimeoutRescue into route stack
hawkw Aug 15, 2023
3adbc31
remove timeout error special-casing
hawkw Aug 30, 2023
e7df13a
Merge branch 'main' into eliza/httproute-retries
hawkw Aug 30, 2023
6099ebf
update lockfile
hawkw Aug 30, 2023
b90c5a9
whoops i accidentally removed the webpki patch
hawkw Aug 30, 2023
6975ae9
remove stuff related to error synthesis
hawkw Aug 30, 2023
3cca5bd
oh i messed up the cargo.toml merge...
hawkw Aug 30, 2023
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
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,7 @@ dependencies = [
"quickcheck",
"thiserror",
"tonic",
"tower",
]

[[package]]
Expand Down Expand Up @@ -1894,8 +1895,7 @@ dependencies = [
[[package]]
name = "linkerd2-proxy-api"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2348745f909668e6de2dbd175eeeac374887ffb33989a0e09766f1807b27cdfe"
source = "git+https://github.com/linkerd/linkerd2-proxy-api?branch=eliza/retry-policy#7790fa05aab1c3c11793852a6d571845b1b3ead9"
dependencies = [
"h2",
"http",
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,7 @@ lto = true
webpki = { git = "https://github.com/linkerd/webpki", branch = "cert-dns-names-0.22" }
boring = { git = "https://github.com/cloudflare/boring" }
tokio-boring = { git = "https://github.com/cloudflare/boring" }

[patch.crates-io.linkerd2-proxy-api]
git = "https://github.com/linkerd/linkerd2-proxy-api"
branch = "eliza/retry-policy"
2 changes: 1 addition & 1 deletion linkerd/app/core/src/errors/respond.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub struct SyntheticHttpResponse {
location: Option<HeaderValue>,
}

#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct EmitHeaders(pub bool);

#[derive(Clone, Debug)]
Expand Down
25 changes: 16 additions & 9 deletions linkerd/app/integration/src/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ pub fn outbound_default(dst: impl ToString) -> outbound::OutboundPolicy {
http1: Some(proxy_protocol::Http1 {
routes: vec![route.clone()],
failure_accrual: None,
retry_budget: None,
}),
http2: Some(proxy_protocol::Http2 {
routes: vec![route],
failure_accrual: None,
retry_budget: None,
}),
opaque: Some(proxy_protocol::Opaque {
routes: vec![outbound_default_opaque_route(dst)],
Expand All @@ -134,28 +136,33 @@ pub fn outbound_default(dst: impl ToString) -> outbound::OutboundPolicy {
}

pub fn outbound_default_http_route(dst: impl ToString) -> outbound::HttpRoute {
use api::http_route;
outbound::HttpRoute {
metadata: Some(api::meta::Metadata {
kind: Some(api::meta::metadata::Kind::Default("default".to_string())),
}),
hosts: Vec::new(),
rules: vec![outbound::http_route::Rule {
matches: vec![http_route::HttpRouteMatch {
path: Some(http_route::PathMatch {
kind: Some(http_route::path_match::Kind::Prefix("/".to_string())),
}),
headers: Vec::new(),
query_params: Vec::new(),
method: None,
}],
matches: vec![match_path_prefix("/")],
filters: Vec::new(),
backends: Some(http_first_available(std::iter::once(backend(dst)))),
request_timeout: None,
retry_policy: None,
}],
}
}

pub fn match_path_prefix(path: impl ToString) -> api::http_route::HttpRouteMatch {
use api::http_route;
http_route::HttpRouteMatch {
path: Some(http_route::PathMatch {
kind: Some(http_route::path_match::Kind::Prefix(path.to_string())),
}),
headers: Vec::new(),
query_params: Vec::new(),
method: None,
}
}

pub fn outbound_default_opaque_route(dst: impl ToString) -> outbound::OpaqueRoute {
use outbound::opaque_route::{self, distribution};
outbound::OpaqueRoute {
Expand Down
15 changes: 14 additions & 1 deletion linkerd/app/integration/src/tests/client_policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use crate::*;
use linkerd2_proxy_api::{self as api};
use policy::outbound::{self, proxy_protocol};

mod retries;

#[tokio::test]
async fn default_http1_route() {
let _trace = trace_init();
Expand Down Expand Up @@ -64,10 +66,12 @@ async fn empty_http1_route() {
rules: Vec::new(),
}],
failure_accrual: None,
retry_budget: None,
}),
http2: Some(proxy_protocol::Http2 {
routes: vec![policy::outbound_default_http_route(&dst)],
failure_accrual: None,
retry_budget: None,
}),
opaque: Some(proxy_protocol::Opaque {
routes: vec![policy::outbound_default_opaque_route(&dst)],
Expand Down Expand Up @@ -149,6 +153,7 @@ async fn empty_http2_route() {
http1: Some(proxy_protocol::Http1 {
routes: vec![policy::outbound_default_http_route(&dst)],
failure_accrual: None,
retry_budget: None,
}),
http2: Some(proxy_protocol::Http2 {
routes: vec![outbound::HttpRoute {
Expand All @@ -157,6 +162,7 @@ async fn empty_http2_route() {
rules: Vec::new(),
}],
failure_accrual: None,
retry_budget: None,
}),
opaque: Some(proxy_protocol::Opaque {
routes: vec![policy::outbound_default_opaque_route(&dst)],
Expand Down Expand Up @@ -224,6 +230,7 @@ async fn header_based_routing() {
policy::backend(dst),
))),
request_timeout: None,
retry_policy: None,
};

let route = outbound::HttpRoute {
Expand All @@ -238,6 +245,7 @@ async fn header_based_routing() {
policy::backend(&dst_world),
))),
request_timeout: None,
retry_policy: None,
},
// x-hello-city: sf | x-hello-city: san francisco
mk_header_rule(
Expand Down Expand Up @@ -267,10 +275,12 @@ async fn header_based_routing() {
http1: Some(proxy_protocol::Http1 {
routes: vec![route.clone()],
failure_accrual: None,
retry_budget: None,
}),
http2: Some(proxy_protocol::Http2 {
routes: vec![route],
failure_accrual: None,
retry_budget: None,
}),
opaque: Some(proxy_protocol::Opaque {
routes: vec![policy::outbound_default_opaque_route(&dst_world)],
Expand Down Expand Up @@ -400,8 +410,8 @@ async fn path_based_routing() {
backends: Some(policy::http_first_available(std::iter::once(
policy::backend(dst),
))),

request_timeout: None,
retry_policy: None,
};

let route = outbound::HttpRoute {
Expand All @@ -416,6 +426,7 @@ async fn path_based_routing() {
policy::backend(&dst_world),
))),
request_timeout: None,
retry_policy: None,
},
// /goodbye/*
mk_path_rule(
Expand Down Expand Up @@ -450,10 +461,12 @@ async fn path_based_routing() {
http1: Some(proxy_protocol::Http1 {
routes: vec![route.clone()],
failure_accrual: None,
retry_budget: None,
}),
http2: Some(proxy_protocol::Http2 {
routes: vec![route],
failure_accrual: None,
retry_budget: None,
}),
opaque: Some(proxy_protocol::Opaque {
routes: vec![policy::outbound_default_opaque_route(&dst_world)],
Expand Down
Loading