Skip to content

Commit e190dae

Browse files
authored
refactor(app): Outline route label extractor (#3337)
* refactor(app): Hoist label extractor out of retry middleware this commit promotes the `RetryLabelExtract` type out of the route retry middleware, and into the metrics submodule. in preparation for generalizing this component, we rename it to `RouteLabelExtract`. Signed-off-by: katelyn martin <[email protected]> * refactor(app): Outline route label extraction this addresses the `TODO` comment, moving the `RouteLabelExtract` type out of the policy route layer function. this defines a method on `MatchedRoute` which may be called to retrieve a `RouteLabelExtract`. that type holds references to the contruction-time information about the route, and can be used to later inspect an outbound request at call-time, returning a `labels::Route` set of labels. this is a helpful piece of reusable glue that is broadly useful in instrumenting our route-level middleware. Signed-off-by: katelyn martin <[email protected]> --------- Signed-off-by: katelyn martin <[email protected]>
1 parent 049e01b commit e190dae

File tree

3 files changed

+44
-30
lines changed

3 files changed

+44
-30
lines changed

linkerd/app/outbound/src/http/logical/policy/route.rs

+2-11
Original file line numberDiff line numberDiff line change
@@ -124,18 +124,9 @@ where
124124
.push_on_service(svc::LoadShed::layer())
125125
.push(filters::NewApplyFilters::<Self, _, _>::layer())
126126
.push({
127-
// TODO(kate): extracting route labels like this should ideally live somewhere
128-
// else, like e.g. the `SetExtensions` middleware.
129-
let mk_extract = |rt: &Self| {
130-
let Route {
131-
parent_ref,
132-
route_ref,
133-
..
134-
} = &rt.params;
135-
retry::RetryLabelExtract(parent_ref.clone(), route_ref.clone())
136-
};
127+
let mk = Self::label_extractor;
137128
let metrics = metrics.retry.clone();
138-
retry::NewHttpRetry::layer_via_mk(mk_extract, metrics)
129+
retry::NewHttpRetry::layer_via_mk(mk, metrics)
139130
})
140131
.check_new::<Self>()
141132
.check_new_service::<Self, http::Request<http::BoxBody>>()

linkerd/app/outbound/src/http/logical/policy/route/metrics/labels.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Prometheus label types.
22
use linkerd_app_core::{
3-
dns, errors, metrics::prom::EncodeLabelSetMut, proxy::http, Error as BoxError,
3+
dns, errors, metrics::prom::EncodeLabelSetMut, proxy::http, svc::ExtractParam,
4+
Error as BoxError,
45
};
56
use prometheus_client::encoding::*;
67

@@ -39,6 +40,9 @@ pub struct GrpcRsp {
3940
pub error: Option<Error>,
4041
}
4142

43+
#[derive(Clone, Debug)]
44+
pub struct RouteLabelExtract(pub ParentRef, pub RouteRef);
45+
4246
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
4347
pub enum Error {
4448
FailFast,
@@ -211,6 +215,37 @@ impl EncodeLabelSet for GrpcRsp {
211215
}
212216
}
213217

218+
// === impl MatchedRoute ===
219+
220+
impl<T, M, F, P> super::super::MatchedRoute<T, M, F, P> {
221+
/// Returns a [`RouteLabelExtract`].
222+
///
223+
/// The extractor returned by this function provides a [`ExtractParam<P, T>`] implementation
224+
/// that can be used to acquire the route-level labels corresponding to a given outbound
225+
/// request.
226+
pub(crate) fn label_extractor(&self) -> RouteLabelExtract {
227+
use super::super::Route;
228+
let Route {
229+
parent_ref,
230+
route_ref,
231+
..
232+
} = &self.params;
233+
234+
RouteLabelExtract(parent_ref.clone(), route_ref.clone())
235+
}
236+
}
237+
238+
// === impl RouteLabelExtract ===
239+
240+
impl<B> ExtractParam<Route, http::Request<B>> for RouteLabelExtract {
241+
fn extract_param(&self, t: &http::Request<B>) -> Route {
242+
let Self(parent, route) = self;
243+
let uri = t.uri();
244+
245+
Route::new(parent.clone(), route.clone(), uri)
246+
}
247+
}
248+
214249
// === impl Error ===
215250

216251
impl Error {

linkerd/app/outbound/src/http/logical/policy/route/retry.rs

+6-18
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
use super::{extensions, metrics::labels::Route as RouteLabels};
2-
use crate::{ParentRef, RouteRef};
1+
use super::{
2+
extensions,
3+
metrics::labels::{Route as RouteLabels, RouteLabelExtract},
4+
};
35
use futures::future::{Either, Ready};
46
use linkerd_app_core::{
57
cause_ref, classify,
68
exp_backoff::ExponentialBackoff,
79
is_caused_by,
810
proxy::http::{self, stream_timeouts::ResponseTimeoutError},
9-
svc::{self, http::h2, ExtractParam},
11+
svc::{self, http::h2},
1012
Error, Result,
1113
};
1214
use linkerd_http_retry::{self as retry, peek_trailers::PeekTrailersBody};
@@ -18,7 +20,7 @@ use tokio::time;
1820
pub struct IsRetry(());
1921

2022
pub type NewHttpRetry<F, N> =
21-
retry::NewHttpRetry<RetryPolicy, RouteLabels, F, RetryLabelExtract, N>;
23+
retry::NewHttpRetry<RetryPolicy, RouteLabels, F, RouteLabelExtract, N>;
2224

2325
#[derive(Clone, Debug)]
2426
pub struct RetryPolicy {
@@ -31,9 +33,6 @@ pub struct RetryPolicy {
3133
pub backoff: Option<ExponentialBackoff>,
3234
}
3335

34-
#[derive(Clone, Debug)]
35-
pub struct RetryLabelExtract(pub ParentRef, pub RouteRef);
36-
3736
pub type RouteRetryMetrics = retry::MetricFamilies<RouteLabels>;
3837

3938
// === impl RetryPolicy ===
@@ -163,14 +162,3 @@ impl RetryPolicy {
163162
false
164163
}
165164
}
166-
167-
// === impl RetryLabelExtract ===
168-
169-
impl<B> ExtractParam<RouteLabels, http::Request<B>> for RetryLabelExtract {
170-
fn extract_param(&self, t: &http::Request<B>) -> RouteLabels {
171-
let Self(parent, route) = self;
172-
let uri = t.uri();
173-
174-
RouteLabels::new(parent.clone(), route.clone(), uri)
175-
}
176-
}

0 commit comments

Comments
 (0)