Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 4 additions & 3 deletions linkerd/app/core/src/classify.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
use crate::profiles;
use linkerd_error::Error;
use linkerd_http_classify as classify;
pub use linkerd_http_classify::{CanClassify, NewClassify};
use linkerd_proxy_http::{HasH2Reason, ResponseTimeoutError};
use std::borrow::Cow;
use tonic as grpc;
use tracing::trace;

#[derive(Clone, Debug)]
pub type NewClassify<N, X = ()> = classify::NewClassify<Request, X, N>;

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Request {
Default,
Profile(profiles::http::ResponseClasses),
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Response {
Default,
Grpc,
Expand Down
12 changes: 4 additions & 8 deletions linkerd/app/inbound/src/http/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,8 @@ impl Param<metrics::ProfileRouteLabels> for ProfileRoute {
}
}

impl classify::CanClassify for ProfileRoute {
type Classify = classify::Request;

fn classify(&self) -> classify::Request {
impl Param<classify::Request> for ProfileRoute {
fn param(&self) -> classify::Request {
self.route.response_classes().clone().into()
}
}
Expand Down Expand Up @@ -416,10 +414,8 @@ impl Param<metrics::EndpointLabels> for Logical {
}
}

impl classify::CanClassify for Logical {
type Classify = classify::Request;

fn classify(&self) -> classify::Request {
impl Param<classify::Request> for Logical {
fn param(&self) -> classify::Request {
classify::Request::default()
}
}
Expand Down
6 changes: 2 additions & 4 deletions linkerd/app/outbound/src/http/logical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,8 @@ impl<T> svc::Param<http::ResponseTimeout> for RouteParams<T> {
}
}

impl<T> classify::CanClassify for RouteParams<T> {
type Classify = classify::Request;

fn classify(&self) -> classify::Request {
impl<T> svc::Param<classify::Request> for RouteParams<T> {
fn param(&self) -> classify::Request {
self.profile.response_classes().clone().into()
}
}
Expand Down
7 changes: 0 additions & 7 deletions linkerd/http-classify/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,3 @@ pub trait ClassifyEos {
/// returned.
fn error(self, error: &Error) -> Self::Class;
}

// Used for stack targets that can produce a `Classify` implementation.
pub trait CanClassify {
type Classify: Classify;

fn classify(&self) -> Self::Classify;
}
36 changes: 26 additions & 10 deletions linkerd/http-classify/src/service.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use linkerd_stack::{layer, NewService, Proxy, Service};
use std::task::{Context, Poll};
use linkerd_stack::{layer, ExtractParam, NewService, Proxy, Service};
use std::{
marker::PhantomData,
task::{Context, Poll},
};

#[derive(Clone, Debug)]
pub struct NewClassify<N> {
pub struct NewClassify<C, X, N> {
inner: N,
extract: X,
_marker: PhantomData<fn() -> C>,
}

#[derive(Clone, Debug)]
Expand All @@ -12,21 +17,32 @@ pub struct Classify<C, P> {
inner: P,
}

impl<N> NewClassify<N> {
pub fn layer() -> impl layer::Layer<N, Service = Self> + Clone + Copy {
layer::mk(|inner| Self { inner })
impl<C, X: Clone, N> NewClassify<C, X, N> {
pub fn layer_via(extract: X) -> impl layer::Layer<N, Service = Self> + Clone {
layer::mk(move |inner| Self {
inner,
extract: extract.clone(),
_marker: PhantomData,
})
}
}

impl<T, N> NewService<T> for NewClassify<N>
impl<C, N> NewClassify<C, (), N> {
pub fn layer() -> impl layer::Layer<N, Service = Self> + Clone {
Self::layer_via(())
}
}

impl<T, C, X, N> NewService<T> for NewClassify<C, X, N>
where
T: super::CanClassify,
C: super::Classify,
X: ExtractParam<C, T>,
N: NewService<T>,
{
type Service = Classify<T::Classify, N::Service>;
type Service = Classify<C, N::Service>;

fn new_service(&self, target: T) -> Self::Service {
let classify = target.classify();
let classify = self.extract.extract_param(&target);
let inner = self.inner.new_service(target);
Classify { classify, inner }
}
Expand Down