Skip to content

Commit

Permalink
Merge pull request #92 from hit-box/tower-trait-configurable
Browse files Browse the repository at this point in the history
Tower trait configurable
  • Loading branch information
AndreyErmilov authored Aug 27, 2023
2 parents cd874a9 + 07d8482 commit a7a2617
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 115 deletions.
29 changes: 20 additions & 9 deletions examples/examples/axum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use hitbox_tower::{
};

use hitbox_redis::RedisBackend;
use hitbox_tower::Cache;
use hitbox_tower::{Cache, EndpointConfig};

async fn handler_result(Path(_name): Path<String>) -> Result<String, String> {
//dbg!("axum::handler_result");
Expand Down Expand Up @@ -41,9 +41,12 @@ async fn main() {
.finish();
tracing::subscriber::set_global_default(subscriber).unwrap();

let backend = RedisBackend::new().unwrap();
let json_cache = Cache::builder()
.backend(backend)
let redis_backend = RedisBackend::new().unwrap();
let inmemory_backend = hitbox_stretto::StrettoBackend::builder(10)
.finalize()
.unwrap();

let json_config = EndpointConfig::builder()
.request(
request::method(Method::GET)
.query("cache", "true")
Expand All @@ -53,14 +56,22 @@ async fn main() {
.response(response::status_code(StatusCode::OK))
.cache_key(extractor::method().query("cache").path("/{path}*"))
.build();
let backend = hitbox_stretto::StrettoBackend::builder(10)
.finalize()
.unwrap();
let health_check = Cache::builder()
.backend(backend) // FIX: it should work withod backend

let health_config = EndpointConfig::builder()
.request(request::path("/health").method(Method::GET))
.disable()
.build();

let json_cache = Cache::builder()
.backend(redis_backend)
.config(json_config)
.build();

let health_check = Cache::builder()
.backend(inmemory_backend) // FIX: it should work withod backend
.config(health_config)
.build();

let app = Router::new()
.route("/greet/:name/", get(handler_result))
.route("/", get(handler))
Expand Down
29 changes: 29 additions & 0 deletions hitbox-tower/src/configurable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use hitbox::policy::PolicyConfig;
use hitbox::predicate::Predicate;
use hitbox::Extractor;
use hitbox_http::{CacheableHttpRequest, CacheableHttpResponse};

type RequestPredicate<ReqBody> =
Box<dyn Predicate<Subject = CacheableHttpRequest<ReqBody>> + Send + Sync>;

type ResponsePredicate<ResBody> =
Box<dyn Predicate<Subject = CacheableHttpResponse<ResBody>> + Send + Sync>;

type RequestExtractor<ResBody> =
Box<dyn Extractor<Subject = CacheableHttpRequest<ResBody>> + Send + Sync>;

pub trait Configurable {
fn request_predicates<ReqBody>(&self) -> RequestPredicate<ReqBody>
where
ReqBody: Send + 'static;

fn response_predicates<ResBody>(&self) -> ResponsePredicate<ResBody>
where
ResBody: Send + 'static;

fn extractors<ReqBody>(&self) -> RequestExtractor<ReqBody>
where
ReqBody: Send + 'static;

fn policy(&self) -> PolicyConfig;
}
88 changes: 88 additions & 0 deletions hitbox-tower/src/configuration/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::configuration::{
ExtractorBuilder, RequestExtractor, RequestPredicate, RequestPredicateBuilder,
ResponsePredicate, ResponsePredicateBuilder,
};
use crate::EndpointConfig;
use hitbox::policy::PolicyConfig;

#[derive(Debug)]
pub struct EndpointConfigBuilder {
pub request_predicates: Vec<RequestPredicate>,
pub response_predicates: Vec<ResponsePredicate>,
pub extractors: Vec<RequestExtractor>,
pub policy: PolicyConfig,
}

impl EndpointConfigBuilder {
pub fn new() -> Self {
Self {
request_predicates: Vec::new(),
response_predicates: Vec::new(),
extractors: Vec::new(),
policy: Default::default(),
}
}

pub fn disable(self) -> Self {
Self {
request_predicates: self.request_predicates,
response_predicates: self.response_predicates,
extractors: self.extractors,
policy: PolicyConfig::Disabled,
}
}

pub fn request(self, predicates: RequestPredicateBuilder) -> Self {
Self {
request_predicates: predicates.build(),
response_predicates: self.response_predicates,
extractors: self.extractors,
policy: self.policy,
}
}

pub fn response(self, predicates: ResponsePredicateBuilder) -> Self {
Self {
request_predicates: self.request_predicates,
response_predicates: predicates.build(),
extractors: self.extractors,
policy: self.policy,
}
}

pub fn cache_key(self, extractors: ExtractorBuilder) -> Self {
Self {
request_predicates: self.request_predicates,
response_predicates: self.response_predicates,
extractors: extractors.build(),
policy: self.policy,
}
}

pub fn build(self) -> EndpointConfig {
EndpointConfig {
request_predicates: self.request_predicates,
response_predicates: self.response_predicates,
extractors: self.extractors,
policy: self.policy,
}
}
}

impl Default for EndpointConfigBuilder {
fn default() -> Self {
Self {
request_predicates: Vec::new(),
response_predicates: vec![ResponsePredicate::StatusCode {
code: http::StatusCode::OK,
}],
extractors: vec![
RequestExtractor::Path {
path: String::from("{path}*"),
},
RequestExtractor::Method,
],
policy: Default::default(),
}
}
}
60 changes: 55 additions & 5 deletions hitbox-tower/src/configuration/endpoint.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::configuration::{RequestExtractor, RequestPredicate, ResponsePredicate};
use crate::configuration::{
builder::EndpointConfigBuilder, RequestExtractor, RequestPredicate, ResponsePredicate,
};
use crate::Configurable;
use hitbox::policy::PolicyConfig;
use hitbox::predicate::Predicate;
use hitbox::Extractor;
Expand All @@ -13,8 +16,9 @@ use hitbox_http::predicates::{
};
use hitbox_http::{CacheableHttpRequest, CacheableHttpResponse};
use serde::{Deserialize, Serialize};
use std::sync::Arc;

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EndpointConfig {
pub request_predicates: Vec<RequestPredicate>,
pub response_predicates: Vec<ResponsePredicate>,
Expand All @@ -32,7 +36,13 @@ impl EndpointConfig {
}
}

pub(crate) fn request_predicates<ReqBody>(
pub fn builder() -> EndpointConfigBuilder {
EndpointConfigBuilder::new()
}
}

impl Configurable for EndpointConfig {
fn request_predicates<ReqBody>(
&self,
) -> Box<dyn Predicate<Subject = CacheableHttpRequest<ReqBody>> + Send + Sync>
where
Expand All @@ -54,7 +64,7 @@ impl EndpointConfig {
})
}

pub(crate) fn response_predicates<ResBody>(
fn response_predicates<ResBody>(
&self,
) -> Box<dyn Predicate<Subject = CacheableHttpResponse<ResBody>> + Send + Sync>
where
Expand All @@ -68,7 +78,7 @@ impl EndpointConfig {
})
}

pub(crate) fn extractors<ReqBody>(
fn extractors<ReqBody>(
&self,
) -> Box<dyn Extractor<Subject = CacheableHttpRequest<ReqBody>> + Send + Sync>
where
Expand All @@ -84,6 +94,46 @@ impl EndpointConfig {
RequestExtractor::Header { key } => Box::new(inner.header(key.to_string())),
})
}

fn policy(&self) -> PolicyConfig {
self.policy.clone()
}
}

impl<C> Configurable for Arc<C>
where
C: Configurable,
{
fn request_predicates<ReqBody>(
&self,
) -> Box<dyn Predicate<Subject = CacheableHttpRequest<ReqBody>> + Send + Sync>
where
ReqBody: Send + 'static,
{
self.as_ref().request_predicates()
}

fn response_predicates<ResBody>(
&self,
) -> Box<dyn Predicate<Subject = CacheableHttpResponse<ResBody>> + Send + Sync>
where
ResBody: Send + 'static,
{
self.as_ref().response_predicates()
}

fn extractors<ReqBody>(
&self,
) -> Box<dyn Extractor<Subject = CacheableHttpRequest<ReqBody>> + Send + Sync>
where
ReqBody: Send + 'static,
{
self.as_ref().extractors()
}

fn policy(&self) -> PolicyConfig {
self.as_ref().policy()
}
}

impl Default for EndpointConfig {
Expand Down
2 changes: 1 addition & 1 deletion hitbox-tower/src/configuration/extractors/request.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RequestExtractor {
Path { path: String },
Method,
Expand Down
1 change: 1 addition & 0 deletions hitbox-tower/src/configuration/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod builder;
mod endpoint;
mod extractors;
mod predicates;
Expand Down
2 changes: 1 addition & 1 deletion hitbox-tower/src/configuration/predicates/request.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::configuration::serializers::method;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RequestPredicate {
Path {
path: String,
Expand Down
2 changes: 1 addition & 1 deletion hitbox-tower/src/configuration/predicates/response.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::configuration::serializers::status_code;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ResponsePredicate {
#[serde(with = "status_code")]
StatusCode { code: http::StatusCode },
Expand Down
Loading

0 comments on commit a7a2617

Please sign in to comment.